/*
 * SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd.
 *
 * SPDX-License-Identifier: MulanPSL-2.0
 */
#![allow(
    non_camel_case_types,
    unused_mut,
    unused_variables,
    unused_assignments,
    improper_ctypes,
    non_snake_case,
    dead_code,
    unreachable_code,
    non_upper_case_globals,
    clashing_extern_declarations,
    unused_unsafe,
    clippy::never_loop,
    clippy::if_same_then_else,
    clippy::while_immutable_condition,
    clippy::upper_case_acronyms
)]

use crate::alias::cmndtag;
use crate::alias::sudoers_comment;
use crate::common::*;
use crate::env::sudo_getenv;
use crate::env::sudo_setenv;
use crate::env::sudo_unsetenv;
use crate::fmtsudoers::tm;
use crate::group_plugin::group_plugin_query;
use crate::ldap_conf::ldap_config;
use crate::ldap_conf::ldap_config_str;
use crate::ldap_conf::ldap_config_str_list;
use crate::ldap_conf::sudo_krb5_ccname_path;
use crate::ldap_conf::sudo_ldap_read_config;
use crate::pwutil::sudo_getgrgid;
use crate::r#match::netgr_matches;
use crate::r#match::sudo_getdomainname;
use crate::set_perms::restore_perms;
use crate::set_perms::set_perms;
use crate::sudoers::sudo_user;
use libc::__errno_location;
use libc::close;
use libc::mkstemp;
use libc::open;
use libc::strncasecmp;

pub type LDAPAVA = ldap_ava;
pub type LDAPRDN = *mut *mut LDAPAVA;
pub type LDAP = ldap;
pub type LDAPDN = *mut LDAPRDN;

pub type size_t = libc::c_ulong;
pub type ber_len_t = libc::c_ulong;

pub const SUDO_LDAP_STARTTLS: libc::c_int = 2;
pub const SUDO_LDAP_SSL: libc::c_int = 1;
pub const LDAP_SUCCESS: libc::c_int = 0;
pub const LDAP_OPT_SUCCESS: libc::c_int = 0;
pub const LDAP_OPT_HOST_NAME: libc::c_int = 48;
pub const LDAP_OPT_RESULT_CODE: libc::c_int = 49;
pub const LDAP_NO_MEMORY: libc::c_int = -10;
pub const I_NETGROUP_TUPLE: libc::c_int = 96;
pub const I_GROUP_PLUGIN: libc::c_int = 78;
pub const LDAP_DN_FORMAT_UFN: libc::c_uint = 64;
pub const LDAP_DN_FORMAT_LDAP: libc::c_uint = 0;
pub const EOVERFLOW: libc::c_int = 75;
pub const LDAP_SCOPE_SUBTREE: libc::c_int = 2;
pub const MAX_UID_T_LEN: libc::c_int = 10;
pub const ENTRY_TYPE_ANY: libc::c_int = 0;
pub const TIMEFILTER_LENGTH: libc::c_int = 115;
pub const ENOENT: libc::c_int = 2;
pub const ALL: libc::c_int = 284;
pub const LDPA_NO_MEMORY: libc::c_int = -10;
pub const SUDO_DSO_DEFAULT: libc::c_int = -2;
pub const O_RDONLY: libc::c_int = 0;
pub const PERM_USER: libc::c_int = 2;
pub const O_NONBLOCK: libc::c_int = 2048;
pub const F_SETFL: libc::c_int = 4;
pub const SUDO_LOCK: libc::c_int = 1;
pub const SASL_CB_LIST_END: libc::c_int = 0;
pub const SASL_CB_USER: libc::c_int = 16385;
pub const LDAP_PARAM_ERROR: libc::c_int = -9;
pub const ALLOCATION_INCREMENT: libc::c_int = 100;

pub type sudo_gss_krb5_ccache_name_t = Option<
    unsafe extern "C" fn(
        *mut libc::c_uint,
        *const libc::c_char,
        *mut *const libc::c_char,
    ) -> libc::c_uint,
>;

#[derive(Copy, Clone)]
#[repr(C)]
pub struct cmndspec {
    pub entries: cmndspec_mid,
    pub runasuserlist: *mut member_list,
    pub runasgrouplist: *mut member_list,
    pub cmnd: *mut member,
    pub tags: cmndtag,
    pub timeout: libc::c_int,
    pub notbefore: time_t,
    pub notafter: time_t,
    pub role: *mut libc::c_char,
    pub type_0: *mut libc::c_char,
}

#[derive(Copy, Clone)]
#[repr(C)]
pub struct sudo_ldap_handle {
    pub ld: *mut LDAP,
    pub pw: *mut passwd,
    pub parse_tree: sudoers_parse_tree,
}

#[derive(Copy, Clone)]
#[repr(C)]
pub struct sudoers_parse_tree {
    pub userspecs: userspec_list,
    pub defaults: defaults_list,
    pub aliases: *mut rbtree,
    pub shost: *const libc::c_char,
    pub lhost: *const libc::c_char,
}

#[derive(Copy, Clone)]
#[repr(C)]
pub struct sasl_interact {
    pub id: libc::c_ulong,
    pub challenge: *const libc::c_char,
    pub prompt: *const libc::c_char,
    pub defresult: *const libc::c_char,
    pub result: *const libc::c_void,
    pub len: libc::c_uint,
}
pub type sasl_interact_t = sasl_interact;

#[derive(Copy, Clone)]
#[repr(C)]
pub struct cmndspec_mid {
    pub tqe_next: *mut cmndspec,
    pub tqe_prev: *mut *mut cmndspec,
}

#[derive(Copy, Clone)]
#[repr(C)]
pub struct cmndspec_list {
    pub tqh_first: *mut cmndspec,
    pub tqh_last: *mut *mut cmndspec,
}

#[derive(Copy, Clone)]
#[repr(C)]
pub struct privilege {
    pub entries: privilege_mid,
    pub ldap_role: *mut libc::c_char,
    pub hostlist: member_list,
    pub cmndlist: cmndspec_list,
    pub defaults: defaults_list,
}

#[derive(Copy, Clone)]
#[repr(C)]
pub struct privilege_mid {
    pub tqe_next: *mut privilege,
    pub tqe_prev: *mut *mut privilege,
}

#[derive(Copy, Clone)]
#[repr(C)]
pub struct privilege_list {
    pub tqh_first: *mut privilege,
    pub tqh_last: *mut *mut privilege,
}

#[derive(Copy, Clone)]
#[repr(C)]
pub struct comment_list {
    pub stqh_first: *mut sudoers_comment,
    pub stqh_last: *mut *mut sudoers_comment,
}

#[derive(Copy, Clone)]
#[repr(C)]
pub struct userspec_list {
    pub tqh_first: *mut userspec,
    pub tqh_last: *mut *mut userspec,
}

#[derive(Copy, Clone)]
#[repr(C)]
pub struct userspec {
    pub entries: userspec_mid,
    pub users: member_list,
    pub privileges: privilege_list,
    pub comments: comment_list,
    pub lineno: libc::c_int,
    pub file: *mut libc::c_char,
}

#[derive(Copy, Clone)]
#[repr(C)]
pub struct userspec_mid {
    pub tqe_next: *mut userspec,
    pub tqe_prev: *mut *mut userspec,
}

#[derive(Copy, Clone)]
#[repr(C)]
pub struct ldap_entry_wrapper {
    pub entry: *mut LDAPMessage,
    pub order: libc::c_double,
}

#[derive(Copy, Clone)]
#[repr(C)]
pub struct berval {
    pub bv_len: ber_len_t,
    pub bv_val: *mut libc::c_char,
}

#[derive(Copy, Clone)]
#[repr(C)]
pub struct ldap_netgroup {
    pub entries: ldap_netgroup_mid,
    pub name: *mut libc::c_char,
}

#[derive(Copy, Clone)]
#[repr(C)]
pub struct ldap_result {
    pub searches: ldap_search_list,
    pub entries: *mut ldap_entry_wrapper,
    pub allocated_entries: libc::c_uint,
    pub nentries: libc::c_uint,
}

#[derive(Copy, Clone)]
#[repr(C)]
pub struct ldap_netgroup_mid {
    pub stqe_next: *mut ldap_netgroup,
}

#[derive(Copy, Clone)]
#[repr(C)]
pub struct ldap_netgroup_list {
    pub stqh_first: *mut ldap_netgroup,
    pub stqh_last: *mut *mut ldap_netgroup,
}

#[derive(Copy, Clone)]
#[repr(C)]
pub struct ldap_search_result {
    pub entries: ldap_search_result_mid,
    pub ldap: *mut LDAP,
    pub searchresult: *mut LDAPMessage,
}

#[derive(Copy, Clone)]
#[repr(C)]
pub struct ldap_search_result_mid {
    pub stqe_next: *mut ldap_search_result,
}

#[derive(Copy, Clone)]
#[repr(C)]
pub struct ldap_search_list {
    pub stqh_first: *mut ldap_search_result,
    pub stqh_last: *mut *mut ldap_search_result,
}

#[derive(Copy, Clone)]
#[repr(C)]
pub struct ldap_ava {
    pub la_attr: berval,
    pub la_value: berval,
    pub la_flags: libc::c_uint,
    pub la_private: *mut libc::c_void,
}

#[derive(Copy, Clone)]
#[repr(C)]
pub struct ldapcontrol {
    pub ldctl_oid: *mut libc::c_char,
    pub ldctl_value: berval,
    pub ldctl_iscritical: libc::c_char,
}

pub type LDAP_SASL_INTERACT_PROC = unsafe extern "C" fn(
    *mut LDAP,
    libc::c_uint,
    *mut libc::c_void,
    *mut libc::c_void,
) -> libc::c_int;

pub type sudo_ldap_iter_t =
    Option<unsafe extern "C" fn(*mut *mut libc::c_void) -> *mut libc::c_char>;

pub type __compar_fn_t =
    Option<unsafe extern "C" fn(*const libc::c_void, *const libc::c_void) -> libc::c_int>;

pub type LDAPControl = ldapcontrol;
pub type __time_t = libc::c_long;
pub type __suseconds_t = libc::c_long;

extern "C" {
    fn sudo_pw_addref(_: *mut passwd);
    fn qsort(__base: *mut libc::c_void, __nmemb: size_t, __size: size_t, __compar: __compar_fn_t);
    fn reallocarray(__ptr: *mut libc::c_void, __nmemb: size_t, __size: size_t)
        -> *mut libc::c_void;
    fn ldap_initialize(ldp: *mut *mut LDAP, url: *const libc::c_char) -> libc::c_int;
    fn sudo_ldap_set_options_conn(ld: *mut LDAP) -> libc::c_int;
    fn sudo_ldap_set_options_global() -> libc::c_int;

    fn strtod(_: *const libc::c_char, _: *mut *mut libc::c_char) -> libc::c_double;
    fn ldap_count_values_len(vals: *mut *mut berval) -> libc::c_int;
    fn ldap_start_tls_s(
        ld: *mut LDAP,
        serverctrls: *mut *mut LDAPControl,
        clientctrls: *mut *mut LDAPControl,
    ) -> libc::c_int;
    fn init_parse_tree(
        parse_tree: *mut sudoers_parse_tree,
        shost: *const libc::c_char,
        lhost: *const libc::c_char,
    );
    fn free_parse_tree(parse_tree: *mut sudoers_parse_tree);
    fn sudo_pw_delref(_: *mut passwd);
    fn ldap_unbind_ext_s(
        ld: *mut LDAP,
        serverctrls: *mut *mut LDAPControl,
        clientctrls: *mut *mut LDAPControl,
    ) -> libc::c_int;

    fn ldap_sasl_bind_s(
        ld: *mut LDAP,
        dn: *const libc::c_char,
        mechanism: *const libc::c_char,
        cred: *mut berval,
        serverctrls: *mut *mut LDAPControl,
        clientctrls: *mut *mut LDAPControl,
        servercredp: *mut *mut berval,
    ) -> libc::c_int;
    fn ldap_sasl_interactive_bind_s(
        ld: *mut LDAP,
        dn: *const libc::c_char,
        saslMechanism: *const libc::c_char,
        serverControls: *mut *mut LDAPControl,
        clientControls: *mut *mut LDAPControl,
        flags: libc::c_uint,
        proc_0: Option<LDAP_SASL_INTERACT_PROC>,
        defaults: *mut libc::c_void,
    ) -> libc::c_int;

    fn write(__fd: libc::c_int, __buf: *const libc::c_void, __n: size_t) -> ssize_t;
    fn read(__fd: libc::c_int, __buf: *mut libc::c_void, __nbytes: size_t) -> ssize_t;
    fn unlink(__name: *const libc::c_char) -> libc::c_int;
    fn sudo_lock_file_v1(fd: libc::c_int, action: libc::c_int) -> bool;
    fn fcntl(__fd: libc::c_int, __cmd: libc::c_int, _: ...) -> libc::c_int;
    fn sudo_ldap_role_to_priv(
        cn: *const libc::c_char,
        hosts: *mut libc::c_void,
        runasusers: *mut libc::c_void,
        runasgroups: *mut libc::c_void,
        cmnds: *mut libc::c_void,
        opts: *mut libc::c_void,
        notbefore: *const libc::c_char,
        notafter: *const libc::c_char,
        warnings: bool,
        store_options: bool,
        iter: sudo_ldap_iter_t,
    ) -> *mut privilege;
    fn sudo_dso_findsym_v1(
        handle: *mut libc::c_void,
        symbol: *const libc::c_char,
    ) -> *mut libc::c_void;
    fn calloc(_: libc::c_ulong, _: libc::c_ulong) -> *mut libc::c_void;
    fn free_userspecs(usl: *mut userspec_list);
    fn sudo_gr_delref(_: *mut group);
    fn sudo_grlist_delref(_: *mut group_list);
    fn sudo_gidlist_delref(_: *mut gid_list);
    fn sudo_strlcat(dst: *mut libc::c_char, src: *const libc::c_char, siz: size_t) -> size_t;
    fn sudo_get_gidlist(pw: *const passwd, type_0: libc::c_uint) -> *mut gid_list;
    fn sudo_get_grlist(pw: *const passwd) -> *mut group_list;
    fn strcasecmp(_: *const libc::c_char, _: *const libc::c_char) -> libc::c_int;
    fn ldap_err2string(err: libc::c_int) -> *mut libc::c_char;
    fn ldap_search_ext_s(
        ld: *mut LDAP,
        base: *const libc::c_char,
        scope: libc::c_int,
        filter: *const libc::c_char,
        attrs: *mut *mut libc::c_char,
        attrsonly: libc::c_int,
        serverctrls: *mut *mut LDAPControl,
        clientctrls: *mut *mut LDAPControl,
        timeout: *mut timeval,
        sizelimit: libc::c_int,
        res: *mut *mut LDAPMessage,
    ) -> libc::c_int;
    fn ldap_next_entry(ld: *mut LDAP, entry: *mut LDAPMessage) -> *mut LDAPMessage;
    fn strdup(_: *const libc::c_char) -> *mut libc::c_char;
    fn ldap_msgfree(lm: *mut LDAPMessage) -> libc::c_int;
    fn ldap_first_entry(ld: *mut LDAP, chain: *mut LDAPMessage) -> *mut LDAPMessage;
    fn snprintf(
        _: *mut libc::c_char,
        _: libc::c_ulong,
        _: *const libc::c_char,
        _: ...
    ) -> libc::c_int;

    fn gmtime(__timer: *const time_t) -> *mut tm;
    fn sudo_warn_nodebug_v1(fmt: *const libc::c_char, _: ...);
    fn time(__timer: *mut time_t) -> time_t;
    fn sudo_ldap_add_default(
        var: *const libc::c_char,
        val: *const libc::c_char,
        op: libc::c_int,
        source: *mut libc::c_char,
        defs: *mut defaults_list,
    ) -> bool;

    fn sudo_ldap_parse_option(
        optstr: *mut libc::c_char,
        varp: *mut *mut libc::c_char,
        valp: *mut *mut libc::c_char,
    ) -> libc::c_int;

    fn rcstr_delref(s: *const libc::c_char);
    fn asprintf(__ptr: *mut *mut libc::c_char, __fmt: *const libc::c_char, _: ...) -> libc::c_int;

    fn rcstr_dup(src: *const libc::c_char) -> *mut libc::c_char;
    fn ldap_str2dn(str: *const libc::c_char, dn: *mut LDAPDN, flags: libc::c_uint) -> libc::c_int;
    fn ldap_dnfree(dn: LDAPDN);
    fn ldap_memfree(p: *mut libc::c_void);
    fn ldap_rdn2str(rdn: LDAPRDN, str: *mut *mut libc::c_char, flags: libc::c_uint) -> libc::c_int;
    fn strftime(
        __s: *mut libc::c_char,
        __maxsize: size_t,
        __format: *const libc::c_char,
        __tp: *const tm,
    ) -> size_t;
    fn ldap_get_dn(ld: *mut LDAP, entry: *mut LDAPMessage) -> *mut libc::c_char;
    static mut sudo_defs_table: [sudo_defs_types; 0];
    fn ldap_value_free_len(vals: *mut *mut berval);
    fn ldap_get_option(
        ld: *mut LDAP,
        option: libc::c_int,
        outvalue: *mut libc::c_void,
    ) -> libc::c_int;
    fn ldap_get_values_len(
        ld: *mut LDAP,
        entry: *mut LDAPMessage,
        target: *const libc::c_char,
    ) -> *mut *mut berval;
    fn ldap_set_option(
        ld: *mut LDAP,
        option: libc::c_int,
        invalue: *const libc::c_void,
    ) -> libc::c_int;
    fn ldap_create(ldp: *mut *mut LDAP) -> libc::c_int;
    static mut sudoers_subsystem_ids: [libc::c_uint; 0];
    fn strlen(_: *const libc::c_char) -> libc::c_ulong;
    static mut ldap_conf: ldap_config;
    fn sudo_warnx_nodebug_v1(fmt: *const libc::c_char, _: ...);
    fn sudo_debug_printf2_v1(
        func: *const libc::c_char,
        file: *const libc::c_char,
        line: libc::c_int,
        level: libc::c_int,
        fmt: *const libc::c_char,
        _: ...
    );
    fn malloc(_: libc::c_ulong) -> *mut libc::c_void;
    fn sudo_strlcpy(dst: *mut libc::c_char, src: *const libc::c_char, siz: size_t) -> size_t;

}

#[derive(Copy, Clone)]
#[repr(C)]
pub struct sudo_nss {
    pub entries: C2RustUnnamed_6,
    pub open: Option<unsafe extern "C" fn(*mut sudo_nss) -> libc::c_int>,
    pub close: Option<unsafe extern "C" fn(*mut sudo_nss) -> libc::c_int>,
    pub parse: Option<unsafe extern "C" fn(*mut sudo_nss) -> *mut sudoers_parse_tree>,
    pub query: Option<unsafe extern "C" fn(*mut sudo_nss, *mut passwd) -> libc::c_int>,
    pub getdefs: Option<unsafe extern "C" fn(*mut sudo_nss) -> libc::c_int>,
    pub handle: *mut libc::c_void,
    pub parse_tree: *mut sudoers_parse_tree,
    pub ret_if_found: bool,
    pub ret_if_notfound: bool,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct C2RustUnnamed_6 {
    pub tqe_next: *mut sudo_nss,
    pub tqe_prev: *mut *mut sudo_nss,
}

#[derive(Copy, Clone)]
#[repr(C)]
pub struct C2RustUnnamed_5 {
    pub tqe_next: *mut userspec,
    pub tqe_prev: *mut *mut userspec,
}

#[no_mangle]
pub fn sudo_ldap_join_uri(mut uri_list: *mut ldap_config_str_list) -> *mut libc::c_char {
    let mut uri: *mut ldap_config_str = std::ptr::null_mut::<ldap_config_str>();
    let mut len: size_t = 0 as libc::c_int as size_t;
    let mut buf: *mut libc::c_char = std::ptr::null_mut::<libc::c_char>();
    unsafe {
        debug_decl!(SUDOERS_DEBUG_LDAP!());
    }

    unsafe {
        uri = (*uri_list).stqh_first;
        while !uri.is_null() {
            if ldap_conf.ssl_mode == SUDO_LDAP_STARTTLS
                && strncasecmp(
                    (*uri).val.as_mut_ptr(),
                    b"ldaps://\0" as *const u8 as *const libc::c_char,
                    8,
                ) == 0
            {
                sudo_warnx!(
                    b"starttls not supported when using ldaps\0" as *const u8
                        as *const libc::c_char,
                );
                ldap_conf.ssl_mode = SUDO_LDAP_SSL;
            }

            /*if ldap_conf.ssl_mode == SUDO_LDAP_STARTTLS {
                if strncasecmp(
                    (*uri).val.as_mut_ptr(),
                    b"ldaps://\0" as *const u8 as *const libc::c_char,
                    8,
                ) == 0
                {
                    sudo_warnx!(
                        b"starttls not supported when using ldaps\0" as *const u8
                            as *const libc::c_char,
                    );
                    ldap_conf.ssl_mode = SUDO_LDAP_SSL;
                }
            }*/
            len += strlen((*uri).val.as_mut_ptr() as *const libc::c_char) + 1;
            uri = (*uri).entries.stqe_next;
        }

        buf = malloc(len) as *mut libc::c_char;
        if len == 0 || buf.is_null() {
            sudo_warnx!(
                b"%s: %s\0" as *const u8 as *const libc::c_char,
                get_function_name!(),
                b"unable to allocate memory\0" as *const u8 as *const libc::c_char
            );
        } else {
            let mut cp: *mut libc::c_char = buf as *mut libc::c_char;

            uri = (*uri_list).stqh_first;
            while !uri.is_null() {
                cp = cp.offset(sudo_strlcpy(
                    cp,
                    (*uri).val.as_mut_ptr(),
                    len.wrapping_sub(cp.offset_from(buf) as size_t),
                ) as isize);
                *cp = ' ' as i32 as libc::c_char;
                cp = cp.offset(1);

                uri = (*uri).entries.stqe_next;
            }
            *cp.offset(-1) = '\u{0}' as i32 as libc::c_char;
        } //unsafe
    }
    unsafe {
        debug_return_str!(buf);
    }
}

#[no_mangle]
pub fn sudo_ldap_init(
    mut ldp: *mut *mut LDAP,
    mut host: *const libc::c_char,
    mut port: libc::c_int,
) -> libc::c_int {
    let mut ld: *mut LDAP = std::ptr::null_mut::<LDAP>();
    let mut ret: libc::c_int = -(11 as libc::c_int);
    unsafe {
        let sudo_debug_subsys_0: libc::c_int = *sudoers_subsystem_ids
            .as_mut_ptr()
            .offset(6 as libc::c_int as isize)
            as libc::c_int;
        debug_decl!(SUDOERS_DEBUG_LDAP!());

        sudo_debug_printf2_v1(
            get_function_name!(),
            get_file_name!(),
            line!() as libc::c_int,
            6 as libc::c_int | sudo_debug_subsys_0 as libc::c_int,
            b"ldap_create()\0" as *const u8 as *const libc::c_char,
        );
        if ldap_conf.debug >= 2 {
            sudo_warnx_nodebug_v1(b"ldap_create()\0" as *const u8 as *const libc::c_char);
        }

        ret = ldap_create(&mut ld);
        if ret != LDAP_SUCCESS {
            debug_return_int!(ret);
        }
        sudo_debug_printf2_v1(
            get_function_name!(),
            get_file_name!(),
            line!() as libc::c_int,
            6 as libc::c_int | sudo_debug_subsys_0 as libc::c_int,
            b"ldap_set_option(LDAP_OPT_HOST_NAME,%s)\0" as *const u8 as *const libc::c_char,
            host,
        );
        if ldap_conf.debug >= 2 {
            sudo_warnx_nodebug_v1(
                b"ldap_set_option(LDAP_OPT_HOST_NAME,%s)\0" as *const u8 as *const libc::c_char,
                host,
            );
        }
        ret = ldap_set_option(ld, LDAP_OPT_HOST_NAME, host as *const libc::c_void);

        *ldp = ld;
    } //unsafe

    unsafe {
        debug_return_int!(ret);
    }
}

#[no_mangle]
pub fn sudo_ldap_get_values_len(
    mut ld: *mut LDAP,
    mut entry: *mut LDAPMessage,
    mut attr: *mut libc::c_char,
    mut rc: *mut libc::c_int,
) -> *mut *mut berval {
    let mut bval: *mut *mut berval = std::ptr::null_mut::<*mut berval>();

    unsafe {
        bval = ldap_get_values_len(ld, entry, attr);
        if bval.is_null() {
            let mut optrc: libc::c_int =
                ldap_get_option(ld, LDAP_OPT_RESULT_CODE, rc as *mut libc::c_void) as libc::c_int;
            if optrc != LDAP_OPT_SUCCESS {
                *rc = optrc;
            }
        } else {
            *rc = LDAP_SUCCESS;
        }
    } //unsafe
    bval
}

#[no_mangle]
pub fn sudo_ldap_check_non_unix_group(
    mut ld: *mut LDAP,
    mut entry: *mut LDAPMessage,
    mut pw: *mut passwd,
) -> libc::c_int {
    let mut bv: *mut *mut berval = std::ptr::null_mut::<*mut berval>();
    let mut p: *mut *mut berval = std::ptr::null_mut::<*mut berval>();
    let mut ret: bool = 0 as libc::c_int != 0;
    let mut val: *mut libc::c_char = std::ptr::null_mut::<libc::c_char>();
    let mut rc: libc::c_int = 0;
    unsafe {
        let sudo_debug_subsys_1: libc::c_int = *sudoers_subsystem_ids
            .as_mut_ptr()
            .offset(6 as libc::c_int as isize)
            as libc::c_int;
        debug_decl!(SUDOERS_DEBUG_LDAP!());

        if entry.is_null() {
            debug_return_int!(ret as libc::c_int);
        }

        bv = sudo_ldap_get_values_len(
            ld,
            entry,
            b"sudoUser\0" as *const u8 as *const libc::c_char as *mut libc::c_char,
            &mut rc,
        );
        if bv.is_null() {
            if rc == LDAP_NO_MEMORY {
                debug_return_int!(-1);
            }
            debug_return_int!(0);
        }

        p = bv;
        while !(*p).is_null() && !ret {
            val = (**p).bv_val;
            if *val as libc::c_int == '+' as i32 {
                if netgr_matches(
                    val,
                    if (*sudo_defs_table
                        .as_mut_ptr()
                        .offset(I_NETGROUP_TUPLE as isize))
                    .sd_un
                    .flag
                        != 0
                    {
                        sudo_user.runhost
                    } else {
                        std::ptr::null::<libc::c_char>()
                    },
                    if (*sudo_defs_table
                        .as_mut_ptr()
                        .offset(I_NETGROUP_TUPLE as isize))
                    .sd_un
                    .flag
                        != 0
                    {
                        sudo_user.srunhost
                    } else {
                        std::ptr::null::<libc::c_char>()
                    },
                    (*pw).pw_name,
                ) {
                    ret = true;
                }

                sudo_debug_printf2_v1(
                    get_function_name!(),
                    get_file_name!(),
                    line!() as libc::c_int,
                    6 as libc::c_int | sudo_debug_subsys_1 as libc::c_int,
                    b"ldap sudoUser netgroup '%s' ... %s\0" as *const u8 as *const libc::c_char,
                    val,
                    if ret {
                        b"MATCH!\0" as *const u8 as *const libc::c_char
                    } else {
                        b"not\0" as *const u8 as *const libc::c_char
                    },
                );
                if ldap_conf.debug >= 2 {
                    sudo_warnx_nodebug_v1(
                        b"ldap sudoUser netgroup '%s' ... %s\0" as *const u8 as *const libc::c_char,
                        val,
                        if ret {
                            b"MATCH\0" as *const u8 as *const libc::c_char
                        } else {
                            b"not\0" as *const u8 as *const libc::c_char
                        },
                    );
                }
            } else {
                if group_plugin_query((*pw).pw_name, val.offset(2_isize), pw as *const passwd) != 0
                {
                    ret = true;
                }
                sudo_debug_printf2_v1(
                    get_function_name!(),
                    get_file_name!(),
                    line!() as libc::c_int,
                    6 as libc::c_int | sudo_debug_subsys_1 as libc::c_int,
                    b"ldap sudoUser non-Unix group '%s' ... %s\0" as *const u8
                        as *const libc::c_char,
                    val,
                    if ret {
                        b"MATCH!\0" as *const u8 as *const libc::c_char
                    } else {
                        b"not\0" as *const u8 as *const libc::c_char
                    },
                );
                if ldap_conf.debug >= 2 {
                    sudo_warnx_nodebug_v1(
                        b"ldap sudoUser non-Unix group '%s' ... %s\0" as *const u8
                            as *const libc::c_char,
                        val,
                        if ret {
                            b"MATCH\0" as *const u8 as *const libc::c_char
                        } else {
                            b"not\0" as *const u8 as *const libc::c_char
                        },
                    );
                }
            }
            p = p.offset(1);
        }

        ldap_value_free_len(bv);
    } //unsafe

    unsafe {
        debug_return_int!(ret as libc::c_int);
    }
}

#[no_mangle]
pub fn sudo_ldap_get_first_rdn(
    mut ld: *mut LDAP,
    mut entry: *mut LDAPMessage,
) -> *mut libc::c_char {
    let mut dn: *mut libc::c_char = std::ptr::null_mut::<libc::c_char>();
    let mut rdn: *mut libc::c_char = std::ptr::null_mut::<libc::c_char>();
    let mut tmpDN: LDAPDN = std::ptr::null_mut::<LDAPRDN>();
    unsafe {
        debug_decl!(SUDOERS_DEBUG_LDAP!());
    }

    unsafe {
        dn = ldap_get_dn(ld, entry);
        if dn.is_null() {
            debug_return_str!(std::ptr::null_mut::<libc::c_char>());
        }
        if ldap_str2dn(dn, &mut tmpDN, LDAP_DN_FORMAT_LDAP) == LDAP_SUCCESS {
            ldap_rdn2str(*tmpDN.offset(0_isize), &mut rdn, LDAP_DN_FORMAT_UFN);
            ldap_dnfree(tmpDN);
        }

        ldap_memfree(dn as *mut libc::c_void);
    } //unsafe
    unsafe {
        debug_return_str!(rdn as *mut libc::c_char);
    }
}

fn sudo_ldap_parse_options(
    mut ld: *mut LDAP,
    mut entry: *mut LDAPMessage,
    mut defs: *mut defaults_list,
) -> bool {
    let mut bv: *mut *mut berval = std::ptr::null_mut::<*mut berval>();
    let mut p: *mut *mut berval = std::ptr::null_mut::<*mut berval>();
    let mut cn: *mut libc::c_char = std::ptr::null_mut::<libc::c_char>();
    let mut cp: *mut libc::c_char = std::ptr::null_mut::<libc::c_char>();
    let mut source: *mut libc::c_char = std::ptr::null_mut::<libc::c_char>();
    let mut ret: bool = 0 as libc::c_int != 0;
    let mut rc: libc::c_int = 0;
    unsafe {
        debug_decl!(SUDOERS_DEBUG_LDAP!());
    }

    bv = sudo_ldap_get_values_len(
        ld,
        entry,
        b"sudoOption\0" as *const u8 as *const libc::c_char as *mut libc::c_char,
        &mut rc,
    );
    unsafe {
        if bv.is_null() {
            if rc == LDAP_NO_MEMORY {
                debug_return_bool!(false);
            }
            debug_return_bool!(true);
        }
    }

    cn = sudo_ldap_get_first_rdn(ld, entry);

    unsafe {
        if asprintf(
            &mut cp,
            b"sudoRole %s\0" as *const u8 as *const libc::c_char,
            if !cn.is_null() {
                cn
            } else {
                b"UNKNOWN\0" as *const u8 as *const libc::c_char
            },
        ) == -1
        {
            sudo_warnx!(
                b"%s: %s\0" as *const u8 as *const libc::c_char,
                get_function_name!(),
                b"unable to allocate memory\0" as *const u8 as *const libc::c_char
            );
            //goto;
            rcstr_delref(source);
            if !cn.is_null() {
                ldap_memfree(cn as *mut libc::c_void);
            }
            ldap_value_free_len(bv);
            debug_return_bool!(ret);
        }
        source = rcstr_dup(cp);
        if source.is_null() {
            sudo_warnx!(
                b"%s: %s\0" as *const u8 as *const libc::c_char,
                get_function_name!(),
                b"unable to allocate memory\0" as *const u8 as *const libc::c_char
            );
            free(cp as *mut libc::c_void);
            //goto;
            rcstr_delref(source);
            if !cn.is_null() {
                ldap_memfree(cn as *mut libc::c_void);
            }
            ldap_value_free_len(bv);
            debug_return_bool!(ret);
        }

        p = bv;
        while !(*p).is_null() {
            let mut var: *mut libc::c_char = std::ptr::null_mut::<libc::c_char>();
            let mut val: *mut libc::c_char = std::ptr::null_mut::<libc::c_char>();
            let mut op: libc::c_int = 0;

            op = sudo_ldap_parse_option((*(*p)).bv_val, &mut var, &mut val);
            if !sudo_ldap_add_default(var, val, op, source, defs) {
                sudo_warnx!(
                    b"%s: %s\0" as *const u8 as *const libc::c_char,
                    get_function_name!(),
                    b"unable to allocate memory\0" as *const u8 as *const libc::c_char
                );
                rcstr_delref(source);
                if !cn.is_null() {
                    ldap_memfree(cn as *mut libc::c_void);
                }
                ldap_value_free_len(bv);
                debug_return_bool!(ret);
            }

            p = p.offset(1_isize);
        }

        ret = true;

        rcstr_delref(source);
        if !cn.is_null() {
            ldap_memfree(cn as *mut libc::c_void);
        }
        ldap_value_free_len(bv);
    } //unsafe
    unsafe {
        debug_return_bool!(ret);
    }
}

#[no_mangle]
pub fn sudo_ldap_timefilter(mut buffer: *mut libc::c_char, mut buffersize: size_t) -> bool {
    let mut tp: *mut tm = std::ptr::null_mut::<tm>();
    let mut now: time_t = 0;
    let mut timebuffer: [libc::c_char; 18] = [0; 18];
    let mut len: libc::c_int = -(1 as libc::c_int);
    unsafe {
        debug_decl!(SUDOERS_DEBUG_LDAP!());
    }

    unsafe {
        time(&mut now);
        tp = gmtime(&now);
        if tp.is_null() {
            sudo_warn!(b"unable to get GMT time\0" as *const u8 as *const libc::c_char,);
            debug_return_bool!(len != -1);
        }

        if strftime(
            timebuffer.as_mut_ptr(),
            ::std::mem::size_of::<[libc::c_char; 18]>() as libc::c_ulong,
            b"%Y%m%d%H%M%S.0Z" as *const u8 as *const libc::c_char,
            tp,
        ) == 0
        {
            sudo_warn!(b"unable to format timestamp\0" as *const u8 as *const libc::c_char,);
            debug_return_bool!(len != -1);
        }

        len = snprintf(
            buffer,
            buffersize,
            b"(&(|(!(sudoNotAfter=*))(sudoNotAfter>=%s))(|(!(sudoNotBefore=*))(sudoNotBefore<=%s)))"
                as *const u8 as *const libc::c_char,
            timebuffer,
            timebuffer,
        );
        if len < 0 || len as size_t >= buffersize {
            sudo_warnx!(
                b"internal error, %s overflow\0" as *const u8 as *const libc::c_char,
                get_function_name!()
            );
            *__errno_location() = EOVERFLOW;
            len = -1;
        }
    } //unsafe

    unsafe {
        debug_return_bool!(len != -1);
    }
}

#[no_mangle]
fn sudo_ldap_build_default_filter() -> *mut libc::c_char {
    unsafe {
        let mut filt: *mut libc::c_char = std::ptr::null_mut::<libc::c_char>();
        debug_decl!(SUDOERS_DEBUG_LDAP!());

        unsafe {
            if (ldap_conf.search_filter).is_null() {
                debug_return_str!(strdup(b"cn=defaults\0" as *const u8 as *const libc::c_char));
            }

            if asprintf(
                &mut filt,
                b"(&%s(cn=defaults))\0" as *const u8 as *const libc::c_char,
                ldap_conf.search_filter,
            ) == -1
            {
                debug_return_str!(std::ptr::null_mut::<libc::c_char>());
            }
        } //unsafe

        debug_return_str!(filt);
    }
}

#[no_mangle]
fn sudo_ldap_value_len(mut value: *const libc::c_char) -> size_t {
    let mut s: *const libc::c_char = std::ptr::null::<libc::c_char>();
    let mut len: size_t = 0 as libc::c_int as size_t;

    s = value;
    unsafe {
        while *s as libc::c_int != '\0' as i32 {
            match *s as u8 as char {
                '\\' | '(' | ')' | '*' => {
                    len = len.wrapping_add(2);
                }
                _ => {}
            }
            s = s.offset(1);
        }

        len = len.wrapping_add(s.offset_from(value) as size_t) as size_t;
    } //unsafe
    len
}

#[no_mangle]
pub fn sudo_ldap_value_cat(
    mut dst: *mut libc::c_char,
    mut src: *const libc::c_char,
    mut size: size_t,
) -> size_t {
    let mut d: *mut libc::c_char = dst;
    let mut s: *const libc::c_char = src;
    let mut n: size_t = size;
    let mut dlen: size_t = 0;

    unsafe {
        loop {
            n = n.wrapping_sub(1);
            if !(n != 0 && *d as libc::c_int != '\0' as i32) {
                break;
            }

            d = d.offset(1);
        }
        dlen = d.offset_from(dst) as size_t;
        n = size.wrapping_sub(dlen);

        if n == 0 {
            return dlen.wrapping_add(strlen(s));
        }

        while *s != '\0' as i32 as libc::c_char {
            match *s as u8 as char {
                '\\' => {
                    if n < 3 {
                        *d = '\0' as i32 as libc::c_char;
                        while *s as libc::c_int != '\0' as i32 {
                            s = s.offset(1);
                        }
                        return dlen.wrapping_add(s.offset_from(src) as size_t);
                    }
                    *d = '\\' as i32 as libc::c_char;
                    d = d.offset(1);
                    *d = '5' as i32 as libc::c_char;
                    d = d.offset(1);
                    *d = 'c' as i32 as libc::c_char;
                    d = d.offset(1);
                    n = n.wrapping_sub(3)
                }
                '(' => {
                    if n < 3 {
                        *d = '\0' as i32 as libc::c_char;
                        while *s as libc::c_int != '\0' as i32 {
                            s = s.offset(1);
                        }
                        return dlen.wrapping_add(s.offset_from(src) as size_t);
                    }
                    *d = '\\' as i32 as libc::c_char;
                    d = d.offset(1);
                    *d = '2' as i32 as libc::c_char;
                    d = d.offset(1);
                    *d = '8' as i32 as libc::c_char;
                    d = d.offset(1);
                    n = n.wrapping_sub(3)
                }
                ')' => {
                    if n < 3 {
                        *d = '\0' as i32 as libc::c_char;
                        while *s as libc::c_int != '\0' as i32 {
                            s = s.offset(1);
                        }
                        return dlen.wrapping_add(s.offset_from(src) as size_t);
                    }
                    *d = '\\' as i32 as libc::c_char;
                    d = d.offset(1);
                    *d = '2' as i32 as libc::c_char;
                    d = d.offset(1);
                    *d = '9' as i32 as libc::c_char;
                    d = d.offset(1);
                    n = n.wrapping_sub(3)
                }
                '*' => {
                    if n < 3 {
                        *d = '\0' as i32 as libc::c_char;
                        while *s as libc::c_int != '\0' as i32 {
                            s = s.offset(1);
                        }
                        return dlen.wrapping_add(s.offset_from(src) as size_t);
                    }
                    *d = '\\' as i32 as libc::c_char;
                    d = d.offset(1);
                    *d = '2' as i32 as libc::c_char;
                    d = d.offset(1);
                    *d = 'a' as i32 as libc::c_char;
                    d = d.offset(1);
                    n = n.wrapping_sub(3)
                }
                _ => {
                    if n < 1 {
                        *d = '\0' as i32 as libc::c_char;
                        while *s as libc::c_int != '\0' as i32 {
                            s = s.offset(1);
                        }
                        return dlen.wrapping_add(s.offset_from(src) as size_t);
                    }
                    *d = *s as i32 as libc::c_char;
                    d = d.offset(1);
                    n = n.wrapping_sub(1);
                }
            }
            s = s.offset(1);
        }
        //done
        *d = '\0' as i32 as libc::c_char;
        while *s as libc::c_int != '\0' as i32 {
            s = s.offset(1);
        }
        dlen.wrapping_add(s.offset_from(src) as size_t)
    } //unsafe
}

#[no_mangle]
fn sudo_ldap_value_dup(mut src: *const libc::c_char) -> *mut libc::c_char {
    let mut dst: *mut libc::c_char = std::ptr::null_mut::<libc::c_char>();
    let mut size: size_t = 0;

    size = sudo_ldap_value_len(src).wrapping_add(1);
    unsafe {
        dst = malloc(size) as *mut libc::c_char;
        if dst.is_null() {
            return std::ptr::null_mut::<libc::c_char>();
        }

        *dst = '\0' as i32 as libc::c_char;
        if sudo_ldap_value_cat(dst, src, size) >= size {
            free(dst as *mut libc::c_void);
            dst = std::ptr::null_mut::<libc::c_char>();
        }
    } //unsafe

    dst
}

#[no_mangle]
pub fn sudo_netgroup_lookup_nested(
    mut ld: *mut LDAP,
    mut base: *mut libc::c_char,
    mut timeout: *mut timeval,
    mut netgroups: *mut ldap_netgroup_list,
    mut start: *mut ldap_netgroup,
) -> bool {
    let mut entry: *mut LDAPMessage = std::ptr::null_mut::<LDAPMessage>();
    let mut result: *mut LDAPMessage = std::ptr::null_mut::<LDAPMessage>();
    let mut filt_len: size_t = 0;
    let mut filt: *mut libc::c_char = std::ptr::null_mut::<libc::c_char>();
    let mut rc: libc::c_int = 0;
    unsafe {
        debug_decl!(SUDOERS_DEBUG_LDAP!());
    }

    unsafe {
        dprintf2!(
            b"Checking for nested netgroups from netgroup_base '%s'\0" as *const u8
                as *const libc::c_char,
            base
        );

        loop {
            let mut ng: *mut ldap_netgroup = std::ptr::null_mut::<ldap_netgroup>();
            let mut old_tail: *mut ldap_netgroup = std::ptr::null_mut::<ldap_netgroup>();

            result = std::ptr::null_mut::<LDAPMessage>();
            old_tail = if ((*netgroups).stqh_first).is_null() {
                std::ptr::null_mut::<ldap_netgroup>()
            } else {
                ((*netgroups).stqh_last as *mut libc::c_char).offset(-(0 as libc::c_ulong as isize))
                    as *mut ldap_netgroup
            };
            filt_len = strlen(ldap_conf.netgroup_search_filter).wrapping_add(7);
            ng = start;
            while !ng.is_null() {
                filt_len = filt_len.wrapping_add(sudo_ldap_value_len((*ng).name).wrapping_add(20));
                ng = (*ng).entries.stqe_next;
            }
            filt = malloc(filt_len) as *mut libc::c_char;
            if filt.is_null() {
                //goto oom;
                sudo_warnx!(
                    b"%s: %s\0" as *const u8 as *const libc::c_char,
                    get_function_name!(),
                    b"unable to allocate memory\0" as *const u8 as *const libc::c_char
                );
                ldap_msgfree(result);
                debug_return_bool!(false);
            }
            if sudo_strlcpy(filt, b"(&\0" as *const u8 as *const libc::c_char, filt_len) >= filt_len
            {
                //goto overflow;
                sudo_warnx!(
                    b"internal error, %s overflow\0" as *const u8 as *const libc::c_char,
                    get_function_name!()
                );
                free(filt as *mut libc::c_void);
                debug_return_bool!(false);
            }
            if sudo_strlcat(filt, ldap_conf.netgroup_search_filter, filt_len) >= filt_len {
                sudo_warnx!(
                    b"internal error, %s overflow\0" as *const u8 as *const libc::c_char,
                    get_function_name!()
                );
                free(filt as *mut libc::c_void);
                debug_return_bool!(false);
            }
            if sudo_strlcat(filt, b"(|\0" as *const u8 as *const libc::c_char, filt_len) >= filt_len
            {
                sudo_warnx!(
                    b"internal error, %s overflow\0" as *const u8 as *const libc::c_char,
                    get_function_name!()
                );
                free(filt as *mut libc::c_void);
                debug_return_bool!(false);
            }

            ng = start;
            while !ng.is_null() {
                if sudo_strlcat(
                    filt,
                    b"(memberNisNetgroup=\0" as *const u8 as *const libc::c_char,
                    filt_len,
                ) >= filt_len
                {
                    sudo_warnx!(
                        b"internal error, %s overflow\0" as *const u8 as *const libc::c_char,
                        get_function_name!()
                    );
                    free(filt as *mut libc::c_void);
                    debug_return_bool!(false);
                }
                if sudo_ldap_value_cat(filt, (*ng).name, filt_len) >= filt_len {
                    sudo_warnx!(
                        b"internal error, %s overflow\0" as *const u8 as *const libc::c_char,
                        get_function_name!()
                    );
                    free(filt as *mut libc::c_void);
                    debug_return_bool!(false);
                }
                if sudo_strlcat(filt, b")\0" as *const u8 as *const libc::c_char, filt_len)
                    >= filt_len
                {
                    sudo_warnx!(
                        b"internal error, %s overflow\0" as *const u8 as *const libc::c_char,
                        get_function_name!()
                    );
                    free(filt as *mut libc::c_void);
                    debug_return_bool!(false);
                }
                ng = (*ng).entries.stqe_next;
            }

            if sudo_strlcat(filt, b"))\0" as *const u8 as *const libc::c_char, filt_len) >= filt_len
            {
                sudo_warnx!(
                    b"internal error, %s overflow\0" as *const u8 as *const libc::c_char,
                    get_function_name!()
                );
                free(filt as *mut libc::c_void);
                debug_return_bool!(false);
            }
            dprintf1!(
                b"ldap netgroup search filter: '%s'\0" as *const u8 as *const libc::c_char,
                filt
            );

            rc = ldap_search_ext_s(
                ld,
                base,
                LDAP_SCOPE_SUBTREE,
                filt,
                std::ptr::null_mut::<*mut libc::c_char>(),
                0,
                std::ptr::null_mut::<*mut LDAPControl>(),
                std::ptr::null_mut::<*mut LDAPControl>(),
                timeout,
                0,
                &mut result,
            );
            free(filt as *mut libc::c_void);

            if rc == LDAP_SUCCESS {
                entry = ldap_first_entry(ld, result);
                while !entry.is_null() {
                    let mut bv: *mut *mut berval = std::ptr::null_mut::<*mut berval>();

                    bv = sudo_ldap_get_values_len(
                        ld,
                        entry,
                        b"cn\0" as *const u8 as *const libc::c_char as *mut libc::c_char,
                        &mut rc,
                    );
                    if bv.is_null() {
                        if rc == LDAP_NO_MEMORY {
                            sudo_warnx!(
                                b"%s: %s\0" as *const u8 as *const libc::c_char,
                                get_function_name!(),
                                b"unable to allocate memory\0" as *const u8 as *const libc::c_char
                            );
                            ldap_msgfree(result);
                            debug_return_bool!(false);
                        }
                    } else {
                        ng = (*netgroups).stqh_first;
                        while !ng.is_null() {
                            if strcasecmp((*ng).name, (**bv).bv_val) == 0 {
                                break;
                            }
                            ng = (*ng).entries.stqe_next;
                        }

                        if ng.is_null() {
                            ng = malloc(::std::mem::size_of::<ldap_netgroup>() as libc::c_ulong)
                                as *mut ldap_netgroup;

                            (*ng).name = strdup((**bv).bv_val);
                            if ng.is_null() || ((*ng).name).is_null() {
                                free(ng as *mut libc::c_void);
                                ldap_value_free_len(bv);
                                sudo_warnx!(
                                    b"%s: %s\0" as *const u8 as *const libc::c_char,
                                    get_function_name!(),
                                    b"unable to allocate memory\0" as *const u8
                                        as *const libc::c_char
                                );
                                ldap_msgfree(result);
                                debug_return_bool!(false);
                            }

                            (*ng).entries.stqe_next = std::ptr::null_mut::<ldap_netgroup>();
                            *(*netgroups).stqh_last = ng;
                            (*netgroups).stqh_last = &mut (*ng).entries.stqe_next;

                            dprintf1!(
                                b"Found new netgroup %s for %s\0" as *const u8
                                    as *const libc::c_char,
                                (*ng).name,
                                base
                            );
                        }
                        ldap_value_free_len(bv);
                    } //same as if bv.is_null->else
                    entry = ldap_next_entry(ld, entry);
                }
            } //end of rc == LDAP_SUCCESS
            ldap_msgfree(result);

            start = if !old_tail.is_null() {
                (*old_tail).entries.stqe_next
            } else {
                (*netgroups).stqh_first
            };

            if start.is_null() {
                break;
            }
        }
    } //unsafe //same as do..while,

    unsafe {
        debug_return_bool!(true);
    }
}

#[no_mangle]
fn sudo_netgroup_lookup(
    mut ld: *mut LDAP,
    mut pw: *mut passwd,
    mut netgroups: *mut ldap_netgroup_list,
) -> bool {
    let mut base: *mut ldap_config_str = std::ptr::null_mut::<ldap_config_str>();
    let mut ng: *mut ldap_netgroup = std::ptr::null_mut::<ldap_netgroup>();
    let mut old_tail: *mut ldap_netgroup = std::ptr::null_mut::<ldap_netgroup>();
    let mut tv: timeval = timeval {
        tv_sec: 0,
        tv_usec: 0,
    };
    let mut tvp: *mut timeval = std::ptr::null_mut::<timeval>();
    let mut entry: *mut LDAPMessage = std::ptr::null_mut::<LDAPMessage>();
    let mut result: *mut LDAPMessage = std::ptr::null_mut::<LDAPMessage>();
    let mut domain: *const libc::c_char = std::ptr::null::<libc::c_char>();
    let mut escaped_domain: *mut libc::c_char = std::ptr::null_mut::<libc::c_char>();
    let mut escaped_user: *mut libc::c_char = std::ptr::null_mut::<libc::c_char>();
    let mut escaped_host: *mut libc::c_char = std::ptr::null_mut::<libc::c_char>();
    let mut escaped_shost: *mut libc::c_char = std::ptr::null_mut::<libc::c_char>();
    let mut filt: *mut libc::c_char = std::ptr::null_mut::<libc::c_char>();
    let mut filt_len: libc::c_int = 0;
    let mut rc: libc::c_int = 0;
    let mut ret: bool = false;
    unsafe {
        debug_decl!(SUDOERS_DEBUG_LDAP!());
    }

    unsafe {
        if ldap_conf.timeout > 0 as libc::c_int {
            tv.tv_sec = ldap_conf.timeout as __time_t;
            tv.tv_usec = 0 as libc::c_int as __suseconds_t;
            tvp = &mut tv;
        }

        domain = sudo_getdomainname();

        'done: loop {
            if !domain.is_null() {
                escaped_domain = sudo_ldap_value_dup((*pw).pw_name);
                if escaped_domain.is_null() {
                    sudo_warnx!(
                        b"%s: %s\0" as *const u8 as *const libc::c_char,
                        get_function_name!(),
                        b"unable to allocate memory\0" as *const u8 as *const libc::c_char
                    );
                    break 'done;
                }
            }
            escaped_user = sudo_ldap_value_dup((*pw).pw_name);
            if escaped_user.is_null() {
                sudo_warnx!(
                    b"%s: %s\0" as *const u8 as *const libc::c_char,
                    get_function_name!(),
                    b"unable to allocate memory\0" as *const u8 as *const libc::c_char
                );
                break 'done;
            }
            if (*sudo_defs_table
                .as_mut_ptr()
                .offset(I_NETGROUP_TUPLE as libc::c_int as isize))
            .sd_un
            .flag
                != 0
            {
                escaped_host = sudo_ldap_value_dup(sudo_user.runhost);
                if sudo_user.runhost == sudo_user.srunhost {
                    escaped_shost = escaped_host;
                } else {
                    escaped_shost = sudo_ldap_value_dup(sudo_user.srunhost);
                }
                if escaped_host.is_null() || escaped_shost.is_null() {
                    sudo_warnx!(
                        b"%s: %s\0" as *const u8 as *const libc::c_char,
                        get_function_name!(),
                        b"unable to allocate memory\0" as *const u8 as *const libc::c_char
                    );
                    break 'done;
                }
            }
            /* Build query, using NIS domain if it is set. */
            if !domain.is_null() {
                if escaped_host != escaped_shost {
                    filt_len = asprintf(&mut filt as *mut *mut libc::c_char,b"(&%s(|(nisNetgroupTriple=\\28,%s,%s\\29)(nisNetgroupTriple=\\28%s,%s,%s\\29)(nisNetgroupTriple=\\28%s,%s,%s\\29)(nisNetgroupTriple=\\28,%s,\\29)(nisNetgroupTriple=\\28%s,%s,\\29)(nisNetgroupTriple=\\28%s,%s,\\29)))\0" as *const u8 as *const libc::c_char,ldap_conf.netgroup_search_filter,escaped_user,escaped_domain,escaped_shost,escaped_user,escaped_domain,escaped_host,escaped_user,escaped_domain,escaped_user,escaped_shost,escaped_user,escaped_host,escaped_user,);
                } else if !escaped_shost.is_null() {
                    filt_len = asprintf(&mut filt as *mut *mut libc::c_char,b"(&%s(|(nisNetgroupTriple=\\28,%s,%s\\29)(nisNetgroupTriple=\\28%s,%s,%s\\29)(nisNetgroupTriple=\\28,%s,\\29)(nisNetgroupTriple=\\28%s,%s,\\29)))\0" as *const u8 as *const libc::c_char,ldap_conf.netgroup_search_filter,escaped_user,escaped_domain,escaped_shost,escaped_user,escaped_domain,escaped_user,escaped_shost,escaped_user,);
                } else {
                    filt_len = asprintf(&mut filt as *mut *mut libc::c_char,b"(&%s(|(nisNetgroupTriple=\\28*,%s,%s\\29)(nisNetgroupTriple=\\28*,%s,\\29)))\0" as *const u8 as *const libc::c_char,ldap_conf.netgroup_search_filter,escaped_user,escaped_domain,escaped_user,);
                }
            } else if escaped_host != escaped_shost {
                filt_len = asprintf(&mut filt as *mut *mut libc::c_char,b"(&%s(|(nisNetgroupTriple=\\28,%s,*\\29)(nisNetgroupTriple=\\28%s,%s,*\\29)(nisNetgroupTriple=\\28%s,%s,*\\29)))\0" as *const u8 as *const libc::c_char,ldap_conf.netgroup_search_filter,escaped_user,escaped_shost,escaped_user,escaped_host,escaped_user,);
            } else if !escaped_shost.is_null() {
                filt_len = asprintf(&mut filt as *mut *mut libc::c_char,b"(&%s(|(nisNetgroupTriple=\\28,%s,*\\29)(nisNetgroupTriple=\\28%s,%s,*\\29)))\0" as *const u8 as *const libc::c_char,ldap_conf.netgroup_search_filter,escaped_user,escaped_shost,escaped_user,);
            } else {
                filt_len = asprintf(
                    &mut filt as *mut *mut libc::c_char,
                    b"(&%s(|(nisNetgroupTriple=\\28*,%s,*\\29)))\0" as *const u8
                        as *const libc::c_char,
                    ldap_conf.netgroup_search_filter,
                    escaped_user,
                );
            } //end of else

            /*} else {
                if escaped_host != escaped_shost {
                    filt_len = asprintf(&mut filt as *mut *mut libc::c_char,b"(&%s(|(nisNetgroupTriple=\\28,%s,*\\29)(nisNetgroupTriple=\\28%s,%s,*\\29)(nisNetgroupTriple=\\28%s,%s,*\\29)))\0" as *const u8 as *const libc::c_char,ldap_conf.netgroup_search_filter,escaped_user,escaped_shost,escaped_user,escaped_host,escaped_user,);
                } else if !escaped_shost.is_null() {
                    filt_len = asprintf(&mut filt as *mut *mut libc::c_char,b"(&%s(|(nisNetgroupTriple=\\28,%s,*\\29)(nisNetgroupTriple=\\28%s,%s,*\\29)))\0" as *const u8 as *const libc::c_char,ldap_conf.netgroup_search_filter,escaped_user,escaped_shost,escaped_user,);
                } else {
                    filt_len = asprintf(
                        &mut filt as *mut *mut libc::c_char,
                        b"(&%s(|(nisNetgroupTriple=\\28*,%s,*\\29)))\0" as *const u8
                            as *const libc::c_char,
                        ldap_conf.netgroup_search_filter,
                        escaped_user,
                    );
                }
            }*/
            //end of else

            if filt_len == -1 {
                sudo_warnx!(
                    b"%s: %s\0" as *const u8 as *const libc::c_char,
                    get_function_name!(),
                    b"unable to allocate memory\0" as *const u8 as *const libc::c_char
                );
                break 'done;
            }

            dprintf1!(
                b"ldap netgroup search filter: '%s'\0" as *const u8 as *const libc::c_char,
                filt
            );

            //834
            base = ldap_conf.netgroup_base.stqh_first;
            while !base.is_null() {
                dprintf1!(
                    b"searching from netgroup_base '%s'\0" as *const u8 as *const libc::c_char,
                    (*base).val
                );
                rc = ldap_search_ext_s(
                    ld,
                    (*base).val.as_mut_ptr(),
                    LDAP_SCOPE_SUBTREE,
                    filt,
                    std::ptr::null_mut::<*mut libc::c_char>(),
                    0 as libc::c_int,
                    std::ptr::null_mut::<*mut LDAPControl>(),
                    std::ptr::null_mut::<*mut LDAPControl>(),
                    tvp,
                    0,
                    &mut result,
                );
                if rc != LDAP_SUCCESS {
                    dprintf1!(
                        b"ldap netgroup search failed: %s\0" as *const u8 as *const libc::c_char,
                        ldap_err2string(rc)
                    );
                    ldap_msgfree(result);
                    continue;
                }

                old_tail = if ((*netgroups).stqh_first).is_null() {
                    std::ptr::null_mut::<ldap_netgroup>()
                } else {
                    ((*netgroups).stqh_last as *mut libc::c_char)
                        .offset(-(0 as libc::c_ulong as isize))
                        as *mut ldap_netgroup
                };

                entry = ldap_first_entry(ld, result);
                while !entry.is_null() {
                    let mut bv: *mut *mut berval = std::ptr::null_mut::<*mut berval>();

                    bv = sudo_ldap_get_values_len(
                        ld,
                        entry,
                        b"cn\0" as *const u8 as *const libc::c_char as *mut libc::c_char,
                        &mut rc,
                    );
                    if bv.is_null() {
                        if rc == LDAP_NO_MEMORY {
                            sudo_warnx!(
                                b"%s: %s\0" as *const u8 as *const libc::c_char,
                                get_function_name!(),
                                b"unable to allocate memory\0" as *const u8 as *const libc::c_char
                            );
                            break 'done;
                        }
                    } else {
                        ng = (*netgroups).stqh_first;
                        while !ng.is_null() {
                            if strcasecmp((*ng).name, (**bv).bv_val) == 0 {
                                break;
                            }
                            ng = (*ng).entries.stqe_next;
                        }
                        if ng.is_null() {
                            ng = malloc(::std::mem::size_of::<ldap_netgroup>() as libc::c_ulong)
                                as *mut ldap_netgroup;
                            (*ng).name = strdup((**bv).bv_val);
                            if ng.is_null() || ((*ng).name).is_null() {
                                free(ng as *mut libc::c_void);
                                ldap_value_free_len(bv);
                                sudo_warnx!(
                                    b"%s: %s\0" as *const u8 as *const libc::c_char,
                                    get_function_name!(),
                                    b"unable to allocate memory\0" as *const u8
                                        as *const libc::c_char
                                );
                                break 'done;
                            }
                            (*ng).entries.stqe_next = std::ptr::null_mut::<ldap_netgroup>();
                            *(*netgroups).stqh_last = ng;
                            (*netgroups).stqh_last = &mut (*ng).entries.stqe_next;
                            dprintf1!(
                                b"Found new netgroup %s for %s\0" as *const u8
                                    as *const libc::c_char,
                                (*ng).name,
                                (*base).val
                            );
                        }
                        ldap_value_free_len(bv);
                    } //same as else
                    entry = ldap_next_entry(ld, entry);
                }
                ldap_msgfree(result);
                result = std::ptr::null_mut::<LDAPMessage>();

                //879
                ng = if !old_tail.is_null() {
                    (*old_tail).entries.stqe_next
                } else {
                    (*netgroups).stqh_first
                };
                if !ng.is_null()
                    && sudo_netgroup_lookup_nested(ld, (*base).val.as_mut_ptr(), tvp, netgroups, ng)
                {
                    break 'done;
                }

                /*if !ng.is_null() {
                    if sudo_netgroup_lookup_nested(ld, (*base).val.as_mut_ptr(), tvp, netgroups, ng)
                    {
                        break 'done;
                    }
                }*/
                //883
                base = (*base).entries.stqe_next;
            }
            //884

            ret = true;

            break 'done;
        } //end of done loop

        free(escaped_domain as *mut libc::c_void);
        free(escaped_user as *mut libc::c_void);
        free(escaped_host as *mut libc::c_void);
        if escaped_host != escaped_shost {
            free(escaped_shost as *mut libc::c_void);
        }
        free(filt as *mut libc::c_void);
        ldap_msgfree(result);
    } //unsafe
    unsafe {
        debug_return_bool!(ret);
    }
}

#[no_mangle]
fn sudo_ldap_build_pass1(mut ld: *mut LDAP, mut pw: *mut passwd) -> *mut libc::c_char {
    let mut buf: *mut libc::c_char = std::ptr::null_mut::<libc::c_char>();
    let mut timebuffer: [libc::c_char; 116] = [0; 116];
    let mut idbuf: [libc::c_char; 11] = [0; 11];
    let mut netgroups: ldap_netgroup_list = ldap_netgroup_list {
        stqh_first: std::ptr::null_mut::<ldap_netgroup>(),
        stqh_last: std::ptr::null_mut::<*mut ldap_netgroup>(),
    };
    let mut ng: *mut ldap_netgroup = std::ptr::null_mut::<ldap_netgroup>();
    let mut gidlist: *mut gid_list = std::ptr::null_mut::<gid_list>();
    let mut grlist: *mut group_list = std::ptr::null_mut::<group_list>();
    let mut grp: *mut group = std::ptr::null_mut::<group>();
    let mut sz: size_t = 0 as libc::c_int as size_t;
    let mut i: libc::c_int = 0;

    unsafe {
        debug_decl!(SUDOERS_DEBUG_LDAP!());
    }

    netgroups.stqh_first = std::ptr::null_mut::<ldap_netgroup>();
    netgroups.stqh_last = &mut netgroups.stqh_first;

    unsafe {
        if ldap_conf.timed != 0 || !(ldap_conf.search_filter).is_null() {
            sz = sz.wrapping_add(3 as size_t);
        }

        if !ldap_conf.search_filter.is_null() {
            sz = sz.wrapping_add(strlen(ldap_conf.search_filter))
        }

        sz = (sz as libc::c_ulong).wrapping_add(
            ((29 as libc::c_int + (12 as libc::c_int + 10 as libc::c_int)) as libc::c_ulong)
                .wrapping_add(sudo_ldap_value_len((*pw).pw_name)),
        ) as size_t as size_t;

        grp = sudo_getgrgid((*pw).pw_gid);
        if !grp.is_null() {
            sz = (sz as libc::c_ulong).wrapping_add(
                (12 as libc::c_int as libc::c_ulong)
                    .wrapping_add(sudo_ldap_value_len((*grp).gr_name)),
            ) as size_t as size_t;
        }

        sz = sz.wrapping_add(13 + MAX_UID_T_LEN as size_t);

        grlist = sudo_get_grlist(pw as *const passwd);
        if !grlist.is_null() {
            let mut i: libc::c_int = 0 as libc::c_int;
            while i < (*grlist).ngroups {
                /*if !(!grp.is_null()
                && strcasecmp(
                    *((*grlist).groups).offset(i as isize) as *const libc::c_char,
                    (*grp).gr_name as *const libc::c_char,
                ) == 0)*/
                if grp.is_null()
                    || strcasecmp(
                        *((*grlist).groups).offset(i as isize) as *const libc::c_char,
                        (*grp).gr_name as *const libc::c_char,
                    ) != 0
                {
                    sz =
                        sz.wrapping_add((12 as size_t).wrapping_add(sudo_ldap_value_len(
                            *((*grlist).groups).offset(i as isize),
                        )));
                }
                i = i.wrapping_add(1);
            }
        }

        gidlist = sudo_get_gidlist(pw, ENTRY_TYPE_ANY as libc::c_uint);
        if !gidlist.is_null() {
            i = 0 as libc::c_int;
            while i < (*gidlist).ngids {
                if (*pw).pw_gid != *((*gidlist).gids).offset(i as isize) {
                    sz = sz.wrapping_add((13 as size_t).wrapping_add(MAX_UID_T_LEN as size_t));
                }
                i += 1;
            }
        }

        if !(ldap_conf.netgroup_base.stqh_first).is_null() {
            dprintf1!(
                b"Looking up netgroups for %s\0" as *const u8 as *const libc::c_char,
                (*pw).pw_name
            );
            if sudo_netgroup_lookup(ld, pw, &mut netgroups) {
                ng = netgroups.stqh_first;
                while !ng.is_null() {
                    sz = (sz as libc::c_ulong).wrapping_add(
                        (14 as libc::c_int as libc::c_ulong).wrapping_add(strlen((*ng).name)),
                    ) as size_t as size_t;
                    ng = (*ng).entries.stqe_next;
                }
            } else {
                loop {
                    ng = netgroups.stqh_first;
                    if ng.is_null() {
                        break;
                    }
                    netgroups.stqh_first = (*netgroups.stqh_first).entries.stqe_next;
                    if (netgroups.stqh_first).is_null() {
                        netgroups.stqh_last = &mut netgroups.stqh_first;
                    }
                    free((*ng).name as *mut libc::c_void);
                    free(ng as *mut libc::c_void);
                }
            }
        }

        'bad: loop {
            'overflow: loop {
                if ldap_conf.timed != 0 {
                    sz = sz.wrapping_add(TIMEFILTER_LENGTH as libc::c_ulong);
                }
                buf = malloc(sz) as *mut libc::c_char;
                if buf.is_null() {
                    break 'bad;
                }
                *buf = '\u{0}' as i32 as libc::c_char;

                if (ldap_conf.timed != 0 || !(ldap_conf.search_filter).is_null())
                    && sudo_strlcpy(buf, b"(&\0" as *const u8 as *const libc::c_char, sz) >= sz
                {
                    break 'overflow;
                }

                /*if ldap_conf.timed != 0 || !(ldap_conf.search_filter).is_null() {
                    if sudo_strlcpy(buf, b"(&\0" as *const u8 as *const libc::c_char, sz) >= sz {
                        break 'overflow;
                    }
                }*/

                if sudo_strlcat(
                    buf,
                    b"(|(sudoUser=\0" as *const u8 as *const libc::c_char,
                    sz,
                ) >= sz
                {
                    break 'overflow;
                }

                if sudo_ldap_value_cat(buf, (*pw).pw_name, sz) >= sz {
                    break 'overflow;
                }

                if sudo_strlcat(buf, b")\0" as *const u8 as *const libc::c_char, sz) >= sz {
                    break 'overflow;
                }

                snprintf(
                    idbuf.as_mut_ptr(),
                    ::std::mem::size_of::<[libc::c_char; 11]>() as libc::c_ulong,
                    b"%u\0" as *const u8 as *const libc::c_char,
                    (*pw).pw_uid,
                );

                if sudo_strlcat(
                    buf,
                    b"(sudoUser=#\0" as *const u8 as *const libc::c_char,
                    sz,
                ) >= sz
                {
                    break 'overflow;
                }

                if sudo_strlcat(buf, idbuf.as_mut_ptr(), sz) >= sz {
                    break 'overflow;
                }

                if sudo_strlcat(buf, b")\0" as *const u8 as *const libc::c_char, sz) >= sz {
                    break 'overflow;
                }

                if !grp.is_null() {
                    if sudo_strlcat(
                        buf,
                        b"(sudoUser=%\0" as *const u8 as *const libc::c_char,
                        sz,
                    ) >= sz
                    {
                        break 'overflow;
                    }

                    if sudo_ldap_value_cat(buf, (*grp).gr_name, sz) >= sz {
                        break 'overflow;
                    }

                    if sudo_strlcat(buf, b")\0" as *const u8 as *const libc::c_char, sz) >= sz {
                        break 'overflow;
                    }
                }

                snprintf(
                    idbuf.as_mut_ptr(),
                    ::std::mem::size_of::<[libc::c_char; 11]>() as libc::c_ulong,
                    b"%u\0" as *const u8 as *const libc::c_char,
                    (*pw).pw_gid,
                );

                if sudo_strlcat(
                    buf,
                    b"(sudoUser=%#\0" as *const u8 as *const libc::c_char,
                    sz,
                ) >= sz
                {
                    break 'overflow;
                }

                if sudo_strlcat(buf, idbuf.as_mut_ptr(), sz) >= sz {
                    break 'overflow;
                }

                if sudo_strlcat(buf, b")\0" as *const u8 as *const libc::c_char, sz) >= sz {
                    break 'overflow;
                }

                if !grlist.is_null() {
                    i = 0;
                    while i < (*grlist).ngroups {
                        /*if !(!grp.is_null()
                        && strcasecmp(
                            (*grlist).groups.offset(i as isize) as *const libc::c_char,
                            (*grp).gr_name,
                        ) == 0)*/
                        if grp.is_null()
                            || strcasecmp(
                                (*grlist).groups.offset(i as isize) as *const libc::c_char,
                                (*grp).gr_name,
                            ) != 0
                        {
                            if sudo_strlcat(
                                buf,
                                b"(sudoUser=%\0" as *const u8 as *const libc::c_char,
                                sz,
                            ) >= sz
                            {
                                break 'overflow;
                            }

                            if sudo_ldap_value_cat(
                                buf,
                                (*grlist).groups.offset(1) as *const libc::c_char,
                                sz,
                            ) >= sz
                            {
                                break 'overflow;
                            }

                            if sudo_strlcat(buf, b")\0" as *const u8 as *const libc::c_char, sz)
                                >= sz
                            {
                                break 'overflow;
                            }
                        }
                        i += 1;
                    }
                }

                if !gidlist.is_null() {
                    i = 0;
                    while i < (*gidlist).ngids {
                        if (*pw).pw_gid != (*gidlist).gids.offset(i as isize) as libc::c_uint {
                            snprintf(
                                idbuf.as_mut_ptr(),
                                ::std::mem::size_of::<[libc::c_char; 11]>() as libc::c_ulong,
                                b"%u\0" as *const u8 as *const libc::c_char,
                                (*gidlist).gids.offset(i as isize) as libc::c_uint,
                            );
                            if sudo_strlcat(
                                buf,
                                b"(sudoUser=%#\0" as *const u8 as *const libc::c_char,
                                sz,
                            ) >= sz
                            {
                                break 'overflow;
                            }

                            if sudo_strlcat(buf, idbuf.as_mut_ptr(), sz) >= sz {
                                break 'overflow;
                            }

                            if sudo_strlcat(buf, b")\0" as *const u8 as *const libc::c_char, sz)
                                >= sz
                            {
                                break 'overflow;
                            }
                        }
                        i += 1;
                    }
                }

                if !gidlist.is_null() {
                    sudo_gidlist_delref(gidlist);
                }
                if !grlist.is_null() {
                    sudo_grlist_delref(grlist);
                }
                if !grp.is_null() {
                    sudo_gr_delref(grp);
                }

                ng = netgroups.stqh_first;
                while !ng.is_null() {
                    netgroups.stqh_first = (*netgroups.stqh_first).entries.stqe_next;
                    if (netgroups.stqh_first).is_null() {
                        netgroups.stqh_last = &mut netgroups.stqh_first;
                    }
                    if sudo_strlcat(
                        buf,
                        b"(sudoUser=+\0" as *const u8 as *const libc::c_char,
                        sz,
                    ) >= sz
                    {
                        break 'overflow;
                    }

                    if sudo_ldap_value_cat(buf, (*ng).name, sz) >= sz {
                        break 'overflow;
                    }

                    if sudo_strlcat(buf, b")\0" as *const u8 as *const libc::c_char, sz) >= sz {
                        break 'overflow;
                    }
                    free((*ng).name as *mut libc::c_void);
                    free(ng as *mut libc::c_void);
                }

                if sudo_strlcat(
                    buf,
                    b"(sudoUser=ALL)\0" as *const u8 as *const libc::c_char,
                    sz,
                ) >= sz
                {
                    break 'overflow;
                }

                if ldap_conf.timed != 0 {
                    if sudo_strlcat(buf, b")\0" as *const u8 as *const libc::c_char, sz) >= sz {
                        break 'overflow;
                    }

                    if !sudo_ldap_timefilter(
                        timebuffer.as_mut_ptr(),
                        ::std::mem::size_of::<[libc::c_char; 116]>() as libc::c_ulong,
                    ) {
                        break 'bad;
                    }

                    if sudo_strlcat(buf, timebuffer.as_mut_ptr(), sz) >= sz {
                        break 'overflow;
                    }
                /*} else if !(ldap_conf.search_filter).is_null() {
                    if sudo_strlcat(buf, b")\0" as *const u8 as *const libc::c_char, sz) >= sz {
                        break 'overflow;
                    }
                }*/
                } else if !(ldap_conf.search_filter).is_null()
                    && sudo_strlcat(buf, b")\0" as *const u8 as *const libc::c_char, sz) >= sz
                {
                    break 'overflow;
                }

                if sudo_strlcat(buf, b")\0" as *const u8 as *const libc::c_char, sz) >= sz {
                    break 'overflow;
                }

                if sudo_strlcat(buf, b")\0" as *const u8 as *const libc::c_char, sz) >= sz {
                    break 'overflow;
                }

                debug_return_str!(buf);
                break 'overflow;
            } // end of goto overflow
            sudo_warnx!(
                b"internal error, %s overflow\0" as *const u8 as *const libc::c_char,
                get_function_name!()
            );
            if !ng.is_null() {
                free((*ng).name as *mut libc::c_void);
                free(ng as *mut libc::c_void);
            }
            *__errno_location() = EOVERFLOW;

            break 'bad;
        }
        ng = netgroups.stqh_first;
        while !ng.is_null() {
            netgroups.stqh_first = (*netgroups.stqh_first).entries.stqe_next;
            if (netgroups.stqh_first).is_null() {
                netgroups.stqh_last = &mut netgroups.stqh_first;
            }
            free((*ng).name as *mut libc::c_void);
            free(ng as *mut libc::c_void);
        }
        free(buf as *mut libc::c_void);
    } //unsafe
    unsafe {
        debug_return_str!(std::ptr::null_mut::<libc::c_char>());
    }
}

#[no_mangle]
fn sudo_ldap_build_pass2() -> *mut libc::c_char {
    let mut filt: *mut libc::c_char = std::ptr::null_mut::<libc::c_char>();
    let mut timebuffer: [libc::c_char; 116] = [0; 116];
    unsafe {
        let mut query_netgroups: bool = (*sudo_defs_table
            .as_mut_ptr()
            .offset(92 as libc::c_int as isize))
        .sd_un
        .flag
            != 0;
        let mut len: libc::c_int = 0;
        debug_decl!(SUDOERS_DEBUG_LDAP!());

        if !(ldap_conf.netgroup_base.stqh_first).is_null() {
            query_netgroups = 0 as libc::c_int != 0;
        }

        if !query_netgroups
            && ((*sudo_defs_table
                .as_mut_ptr()
                .offset(78 as libc::c_int as isize))
            .sd_un
            .str_0)
                .is_null()
        {
            *__errno_location() = ENOENT as libc::c_int;
            debug_return_str!(std::ptr::null_mut::<libc::c_char>());
        }

        if ldap_conf.timed != 0
            && !sudo_ldap_timefilter(
                timebuffer.as_mut_ptr(),
                ::std::mem::size_of::<[libc::c_char; 116]>() as libc::c_ulong,
            )
        {
            debug_return_str!(std::ptr::null_mut::<libc::c_char>());
        }
        /*if ldap_conf.timed != 0 {
            if !sudo_ldap_timefilter(
                timebuffer.as_mut_ptr(),
                ::std::mem::size_of::<[libc::c_char; 116]>() as libc::c_ulong,
            ) {
                debug_return_str!(std::ptr::null_mut::<libc::c_char>());
            }
        }*/

        if query_netgroups as libc::c_int != 0
            && !((*sudo_defs_table
                .as_mut_ptr()
                .offset(78 as libc::c_int as isize))
            .sd_un
            .str_0)
                .is_null()
        {
            len = asprintf(
                &mut filt as *mut *mut libc::c_char,
                b"%s%s(|(sudoUser=+*)(sudoUser=%%:*))%s%s\0" as *const u8 as *const libc::c_char,
                if ldap_conf.timed != 0 || !(ldap_conf.search_filter).is_null() {
                    b"(&\0" as *const u8 as *const libc::c_char
                } else {
                    b"\0" as *const u8 as *const libc::c_char
                },
                if !(ldap_conf.search_filter).is_null() {
                    ldap_conf.search_filter
                } else {
                    b"\0" as *const u8 as *const libc::c_char
                },
                if ldap_conf.timed != 0 {
                    timebuffer.as_mut_ptr()
                } else {
                    b"\0" as *const u8 as *const libc::c_char
                },
                if ldap_conf.timed != 0 || !(ldap_conf.search_filter).is_null() {
                    b")\0" as *const u8 as *const libc::c_char
                } else {
                    b"\0" as *const u8 as *const libc::c_char
                },
            );
        } else {
            len = asprintf(
                &mut filt as *mut *mut libc::c_char,
                b"(&%s(sudoUser=*)(sudoUser=%s*)%s)\0" as *const u8 as *const libc::c_char,
                if !(ldap_conf.search_filter).is_null() {
                    ldap_conf.search_filter
                } else {
                    b"\0" as *const u8 as *const libc::c_char
                },
                if query_netgroups as libc::c_int != 0 {
                    b"+\0" as *const u8 as *const libc::c_char
                } else {
                    b"%:\0" as *const u8 as *const libc::c_char
                },
                if ldap_conf.timed != 0 {
                    timebuffer.as_mut_ptr()
                } else {
                    b"\0" as *const u8 as *const libc::c_char
                },
            );
        }

        if len == -1 {
            filt = std::ptr::null_mut::<libc::c_char>();
        }
    } //unsafe

    unsafe {
        debug_return_str!(filt);
    }
}

#[no_mangle]
pub unsafe extern "C" fn berval_iter(mut vp: *mut *mut libc::c_void) -> *mut libc::c_char {
    let mut bv: *mut *mut berval = *vp as *mut *mut berval;
    unsafe {
        *vp = bv.offset(1 as libc::c_int as isize) as *mut libc::c_void;
        if !(*bv).is_null() {
            (**bv).bv_val
        } else {
            std::ptr::null_mut::<libc::c_char>()
        }
    } //unsafe
}

#[no_mangle]
pub fn ldap_to_sudoers(
    mut ld: *mut LDAP,
    mut lres: *mut ldap_result,
    mut ldap_userspecs: *mut userspec_list,
) -> bool {
    let mut current_block: u64;
    let mut us: *mut userspec = std::ptr::null_mut::<userspec>();
    let mut m: *mut member = std::ptr::null_mut::<member>();
    let mut i: libc::c_uint = 0;
    let mut rc: libc::c_int = 0;
    unsafe {
        debug_decl!(SUDOERS_DEBUG_LDAP!());
    }

    unsafe {
        us = calloc(
            1 as libc::c_int as libc::c_ulong,
            ::std::mem::size_of::<userspec>() as libc::c_ulong,
        ) as *mut userspec;
        if us.is_null() {
            sudo_warnx!(
                b"%s: %s\0" as *const u8 as *const libc::c_char,
                get_function_name!(),
                b"unable to allocate memory\0" as *const u8 as *const libc::c_char
            );
            free_userspecs(ldap_userspecs);
            debug_return_bool!(false);
        }
        (*us).users.tqh_first = std::ptr::null_mut::<member>();
        (*us).users.tqh_last = &mut (*us).users.tqh_first;

        (*us).privileges.tqh_first = std::ptr::null_mut::<privilege>();
        (*us).privileges.tqh_last = &mut (*us).privileges.tqh_first;

        (*us).comments.stqh_first = std::ptr::null_mut::<sudoers_comment>();
        (*us).comments.stqh_last = &mut (*us).comments.stqh_first;

        (*us).entries.tqe_next = std::ptr::null_mut::<userspec>();
        (*us).entries.tqe_prev = (*ldap_userspecs).tqh_last;
        *(*ldap_userspecs).tqh_last = us;
        (*ldap_userspecs).tqh_last = &mut (*us).entries.tqe_next;

        m = calloc(
            1 as libc::c_int as libc::c_ulong,
            ::std::mem::size_of::<member>() as libc::c_ulong,
        ) as *mut member;
        if m.is_null() {
            sudo_warnx!(
                b"%s: %s\0" as *const u8 as *const libc::c_char,
                get_function_name!(),
                b"unable to allocate memory\0" as *const u8 as *const libc::c_char
            );
            free_userspecs(ldap_userspecs);
            debug_return_bool!(false);
        }
        (*m).type0 = ALL as libc::c_int as libc::c_short;
        (*m).entries.tqe_next = std::ptr::null_mut::<member>();
        (*m).entries.tqe_prev = (*us).users.tqh_last;
        *(*us).users.tqh_last = m;
        (*us).users.tqh_last = &mut (*m).entries.tqe_next;

        i = 0;
        while i < (*lres).nentries {
            let mut entry: *mut LDAPMessage = (*((*lres).entries).offset(i as isize)).entry;
            let mut cmnds: *mut *mut berval = std::ptr::null_mut::<*mut berval>();
            let mut hosts: *mut *mut berval = std::ptr::null_mut::<*mut berval>();
            let mut runasusers: *mut *mut berval = std::ptr::null_mut::<*mut berval>();
            let mut runasgroups: *mut *mut berval = std::ptr::null_mut::<*mut berval>();
            let mut opts: *mut *mut berval = std::ptr::null_mut::<*mut berval>();
            let mut notbefore: *mut *mut berval = std::ptr::null_mut::<*mut berval>();
            let mut notafter: *mut *mut berval = std::ptr::null_mut::<*mut berval>();
            let mut priv_0: *mut privilege = std::ptr::null_mut::<privilege>();
            let mut cn: *mut libc::c_char = std::ptr::null_mut::<libc::c_char>();

            'cleanup: loop {
                cmnds = sudo_ldap_get_values_len(
                    ld,
                    entry,
                    b"sudoCommand\0" as *const u8 as *const libc::c_char as *mut libc::c_char,
                    &mut rc,
                );
                if cmnds.is_null() {
                    if rc == LDAP_NO_MEMORY {
                        break 'cleanup;
                    }
                    i += 1;
                    continue;
                }

                cn = sudo_ldap_get_first_rdn(ld, entry);
                if cn.is_null() {
                    break 'cleanup;
                }

                hosts = sudo_ldap_get_values_len(
                    ld,
                    entry,
                    b"sudoHost\0" as *const u8 as *const libc::c_char as *mut libc::c_char,
                    &mut rc,
                );
                if rc == LDAP_NO_MEMORY as libc::c_int {
                    break 'cleanup;
                }

                runasusers = sudo_ldap_get_values_len(
                    ld,
                    entry,
                    b"sudoRunAsUser\0" as *const u8 as *const libc::c_char as *mut libc::c_char,
                    &mut rc,
                );
                if runasusers.is_null() {
                    if rc != LDAP_NO_MEMORY {
                        runasusers = sudo_ldap_get_values_len(
                            ld,
                            entry,
                            b"sudoRunAs\0" as *const u8 as *const libc::c_char as *mut libc::c_char,
                            &mut rc,
                        );
                    }
                    if rc == LDAP_NO_MEMORY {
                        break 'cleanup;
                    }
                }

                runasgroups = sudo_ldap_get_values_len(
                    ld,
                    entry,
                    b"sudoRunAsGroup\0" as *const u8 as *const libc::c_char as *mut libc::c_char,
                    &mut rc,
                );
                if rc == LDAP_NO_MEMORY {
                    break 'cleanup;
                }

                notbefore = sudo_ldap_get_values_len(
                    ld,
                    entry,
                    b"sudoNotBefore\0" as *const u8 as *const libc::c_char as *mut libc::c_char,
                    &mut rc,
                );
                if rc == LDAP_NO_MEMORY {
                    break 'cleanup;
                }

                notbefore = sudo_ldap_get_values_len(
                    ld,
                    entry,
                    b"sudoNotAfter\0" as *const u8 as *const libc::c_char as *mut libc::c_char,
                    &mut rc,
                );
                if rc == LDAP_NO_MEMORY {
                    break 'cleanup;
                }

                opts = sudo_ldap_get_values_len(
                    ld,
                    entry,
                    b"sudoOption\0" as *const u8 as *const libc::c_char as *mut libc::c_char,
                    &mut rc,
                );
                if rc == LDAP_NO_MEMORY {
                    break 'cleanup;
                }

                priv_0 = sudo_ldap_role_to_priv(
                    cn,
                    hosts as *mut libc::c_void,
                    runasusers as *mut libc::c_void,
                    runasgroups as *mut libc::c_void,
                    cmnds as *mut libc::c_void,
                    opts as *mut libc::c_void,
                    if !notbefore.is_null() {
                        (**notbefore.offset(0 as libc::c_int as isize)).bv_val
                    } else {
                        std::ptr::null_mut::<libc::c_char>()
                    },
                    if !notafter.is_null() {
                        (**notafter.offset(0 as libc::c_int as isize)).bv_val
                    } else {
                        std::ptr::null_mut::<libc::c_char>()
                    },
                    0 as libc::c_int != 0,
                    1 as libc::c_int != 0,
                    Some(
                        berval_iter
                            as unsafe extern "C" fn(*mut *mut libc::c_void) -> *mut libc::c_char,
                    ),
                );

                break 'cleanup;
            } //end of loop

            //c: cleanup:
            if !cn.is_null() {
                ldap_memfree(cn as *mut libc::c_void);
            }

            if !cmnds.is_null() {
                ldap_value_free_len(cmnds);
            }

            if !hosts.is_null() {
                ldap_value_free_len(hosts);
            }

            if !runasusers.is_null() {
                ldap_value_free_len(runasusers);
            }

            if !runasgroups.is_null() {
                ldap_value_free_len(runasgroups);
            }

            if !opts.is_null() {
                ldap_value_free_len(opts);
            }

            if !notbefore.is_null() {
                ldap_value_free_len(notbefore);
            }

            if !notafter.is_null() {
                ldap_value_free_len(notafter);
            }

            if priv_0.is_null() {
                sudo_warnx!(
                    b"%s: %s\0" as *const u8 as *const libc::c_char,
                    get_function_name!(),
                    b"unable to allocate memory\0" as *const u8 as *const libc::c_char
                );
                free_userspecs(ldap_userspecs);
                debug_return_bool!(false);
            }

            (*priv_0).entries.tqe_next = std::ptr::null_mut::<privilege>();
            (*priv_0).entries.tqe_prev = (*us).privileges.tqh_last;
            *(*us).privileges.tqh_last = priv_0;
            (*us).privileges.tqh_last = &mut (*priv_0).entries.tqe_next;

            i += 1;
        }
    } //unsafe //end of while

    unsafe {
        debug_return_bool!(true);
    }
    /*
    oom:
            sudo_warnx!(b"%s: %s\0" as *const u8 as *const libc::c_char,get_function_name!(),b"unable to allocate memory\0" as *const u8 as *const libc::c_char );
            free_userspecs(ldap_userspecs);
            debug_return_bool!(false);
    */
}

static mut sudo_gss_krb5_ccache_name: sudo_gss_krb5_ccache_name_t = None;

#[no_mangle]
pub fn sudo_set_krb5_ccache_name(
    mut name: *const libc::c_char,
    mut old_name: *mut *const libc::c_char,
) -> libc::c_int {
    let mut ret: libc::c_int = 0 as libc::c_int;
    let mut junk: libc::c_uint = 0;
    static mut initialized: bool = false;
    unsafe {
        debug_decl!(SUDOERS_DEBUG_LDAP!());
    }

    unsafe {
        if !initialized {
            sudo_gss_krb5_ccache_name = ::std::mem::transmute::<
                *mut libc::c_void,
                sudo_gss_krb5_ccache_name_t,
            >(sudo_dso_findsym_v1(
                SUDO_DSO_DEFAULT as *mut libc::c_void,
                b"gss_krb5_ccache_name\0" as *const u8 as *const libc::c_char,
            ));
            initialized = 1 as libc::c_int != 0;
        }

        if sudo_gss_krb5_ccache_name.is_some() {
            ret = sudo_gss_krb5_ccache_name.expect("non-null function pointer")(
                &mut junk, name, old_name,
            ) as libc::c_int;
        } else if !old_name.is_null() {
            *old_name = sudo_getenv(b"KRB5CCNAME\0" as *const u8 as *const libc::c_char);
        }

        /*} else {
            if !old_name.is_null() {
                *old_name = sudo_getenv(b"KRB5CCNAME\0" as *const u8 as *const libc::c_char);
            }
        }*/

        if !name.is_null() && *name as libc::c_int != '\u{0}' as i32 {
            if sudo_setenv(
                b"KRB5CCNAME\0" as *const u8 as *const libc::c_char,
                name,
                1 as libc::c_int,
            ) == -(1 as libc::c_int)
            {
                ret = -(1 as libc::c_int);
            }
        } else if sudo_unsetenv(b"KRB5CCNAME\0" as *const u8 as *const libc::c_char)
            == -(1 as libc::c_int)
        {
            ret = -(1 as libc::c_int);
        }

        /*} else {
            if sudo_unsetenv(b"KRB5CCNAME\0" as *const u8 as *const libc::c_char)
                == -(1 as libc::c_int)
            {
                ret = -(1 as libc::c_int);
            }
        }*/
    } //unsafe

    unsafe {
        debug_return_int!(ret);
    }
}

#[no_mangle]
pub fn sudo_krb5_copy_cc_file(mut old_ccname: *const libc::c_char) -> *mut libc::c_char {
    let mut nfd: libc::c_int = 0;
    let mut ofd: libc::c_int = -(1 as libc::c_int);
    let mut nread: ssize_t = 0;
    let mut nwritten: ssize_t = -(1 as libc::c_int) as ssize_t;
    static mut new_ccname: [libc::c_char; 21] = [0; 21];
    let mut buf: [libc::c_char; 10240] = [0; 10240];
    let mut ret: *mut libc::c_char = std::ptr::null_mut::<libc::c_char>();
    unsafe {
        let sudo_debug_subsys_3: libc::c_int = *sudoers_subsystem_ids
            .as_mut_ptr()
            .offset(6 as libc::c_int as isize)
            as libc::c_int;

        debug_decl!(SUDOERS_DEBUG_LDAP!());
        old_ccname = sudo_krb5_ccname_path(old_ccname);

        if !old_ccname.is_null() {
            if !set_perms(PERM_USER) {
                if ofd != -1 {
                    close(ofd);
                }
                debug_return_str!(ret);
            }
            ofd = open(
                old_ccname,
                O_RDONLY as libc::c_int | O_NONBLOCK as libc::c_int,
            );
            if !restore_perms() {
                if ofd != -1 {
                    close(ofd);
                }
                debug_return_str!(ret);
            }

            if ofd != -1 {
                fcntl(ofd, F_SETFL as libc::c_int, 0 as libc::c_int);
                if sudo_lock_file_v1(ofd, SUDO_LOCK as libc::c_int) {
                    snprintf(
                        new_ccname.as_mut_ptr(),
                        ::std::mem::size_of::<[libc::c_char; 21]>() as libc::c_ulong,
                        b"%s%s\0" as *const u8 as *const libc::c_char,
                        b"/tmp/\0" as *const u8 as *const libc::c_char,
                        b"sudocc_XXXXXXXX\0" as *const u8 as *const libc::c_char,
                    );
                    nfd = mkstemp(new_ccname.as_mut_ptr());
                    if nfd != -1 {
                        'write_error: loop {
                            sudo_debug_printf2_v1(
                                get_function_name!(),
                                get_file_name!(),
                                line!() as libc::c_int,
                                6 as libc::c_int
                                    | SUDO_DEBUG_LINENO
                                    | sudo_debug_subsys_3 as libc::c_int,
                                b"copy ccache %s -> %s\0" as *const u8 as *const libc::c_char,
                                old_ccname,
                                new_ccname,
                            );
                            nread = read(
                                ofd,
                                buf.as_mut_ptr() as *mut libc::c_void,
                                ::std::mem::size_of::<[libc::c_char; 10240]>() as libc::c_ulong,
                            );
                            while nread > 0 {
                                let mut off: ssize_t = 0 as libc::c_int as ssize_t;
                                loop {
                                    nwritten = write(
                                        nfd,
                                        buf.as_mut_ptr().offset(off as isize)
                                            as *const libc::c_void,
                                        (nread - off) as size_t,
                                    );
                                    if nwritten == -1 {
                                        sudo_warnx!(
                                            b"error writing to %s\0" as *const u8
                                                as *const libc::c_char,
                                            new_ccname
                                        );
                                        break 'write_error;
                                    }
                                    off += nwritten;
                                    if off >= nread {
                                        break;
                                    }
                                } //same as loop
                            } //same as nread>0
                            if nread == -1 {
                                sudo_warnx!(
                                    b"unable to read %s\0" as *const u8 as *const libc::c_char,
                                    new_ccname
                                );
                            }

                            break 'write_error;
                        } // end of write_error
                          //c: write_error
                        close(nfd);
                        if nread != -1 && nwritten != -1 {
                            ret = new_ccname.as_mut_ptr();
                        } else {
                            unlink(new_ccname.as_mut_ptr());
                        }
                    } else {
                        sudo_warnx!(
                            b"unable to create temp file %s\0" as *const u8 as *const libc::c_char,
                            new_ccname
                        );
                    } //same as nfd != -1
                } //same as sudo_lock_file_v1
            } else {
                sudo_debug_printf2_v1(
                    get_function_name!(),
                    get_file_name!(),
                    line!() as libc::c_int,
                    6 as libc::c_int | sudo_debug_subsys_3 as libc::c_int,
                    b"unable to open %s\0" as *const u8 as *const libc::c_char,
                    old_ccname,
                );
            }
        } //same as !old_ccname.is_null()

        //c: done;
        if ofd != -1 {
            close(ofd);
        }
    } //unsafe
    unsafe {
        debug_return_str!(ret);
    }
}

#[no_mangle]
pub unsafe extern "C" fn sudo_ldap_sasl_interact(
    mut ld: *mut LDAP,
    mut flags: libc::c_uint,
    mut _auth_id: *mut libc::c_void,
    mut _interact: *mut libc::c_void,
) -> libc::c_int {
    let mut auth_id: *mut libc::c_char = _auth_id as *mut libc::c_char;
    let mut interact: *mut sasl_interact_t = _interact as *mut sasl_interact_t;
    let mut ret: libc::c_int = 0 as libc::c_int;
    debug_decl!(SUDOERS_DEBUG_LDAP!());

    while (*interact).id != 0 as libc::c_int as libc::c_ulong {
        if (*interact).id != SASL_CB_USER as libc::c_ulong {
            sudo_warnx!(
                b"sudo_ldap_sasl_interact: unexpected interact id %lu\0" as *const u8
                    as *const libc::c_char,
                (*interact).id
            );
            ret = LDAP_PARAM_ERROR;
            break;
        }

        if !auth_id.is_null() {
            (*interact).result = auth_id as *const libc::c_void;
        } else if !((*interact).defresult).is_null() {
            (*interact).result = (*interact).defresult as *const libc::c_void;
        } else {
            (*interact).result = b"\0" as *const u8 as *const libc::c_char as *const libc::c_void;
        }

        (*interact).len = strlen((*interact).result as *const libc::c_char) as libc::c_uint;

        dprintf2!(
            b"sudo_ldap_sasl_interact: SASL_CB_USER %s\0" as *const u8 as *const libc::c_char,
            (*interact).result as *const libc::c_char
        );
        interact = interact.offset(1);
    }

    debug_return_int!(ret);
}

#[no_mangle]
pub fn sudo_ldap_result_alloc() -> *mut ldap_result {
    let mut result: *mut ldap_result = std::ptr::null_mut::<ldap_result>();
    unsafe {
        debug_decl!(SUDOERS_DEBUG_LDAP!());
    }

    unsafe {
        result = calloc(
            1 as libc::c_int as libc::c_ulong,
            ::std::mem::size_of::<ldap_result>() as libc::c_ulong,
        ) as *mut ldap_result;
        if !result.is_null() {
            (*result).searches.stqh_first = std::ptr::null_mut::<ldap_search_result>();
            (*result).searches.stqh_last = &mut (*result).searches.stqh_first;
        }
    } //unsafe

    unsafe {
        debug_return_ptr!(result);
    }
}

#[no_mangle]
pub fn sudo_ldap_result_free(mut lres: *mut ldap_result) {
    let mut s: *mut ldap_search_result = std::ptr::null_mut::<ldap_search_result>();
    unsafe {
        debug_decl!(SUDOERS_DEBUG_LDAP!());
    }

    unsafe {
        if !lres.is_null() {
            if (*lres).nentries != 0 {
                free((*lres).entries as *mut libc::c_void);
                (*lres).entries = std::ptr::null_mut::<ldap_entry_wrapper>();
            }

            s = (*lres).searches.stqh_first;
            while !s.is_null() {
                (*lres).searches.stqh_first = (*(*lres).searches.stqh_first).entries.stqe_next;
                if ((*lres).searches.stqh_first).is_null() {
                    (*lres).searches.stqh_last = &mut (*lres).searches.stqh_first;
                }
                ldap_msgfree((*s).searchresult);
                free(s as *mut libc::c_void);
            }

            free(lres as *mut libc::c_void);
        }
    } //unsafe
    unsafe {
        debug_return!();
    }
}

#[no_mangle]
fn sudo_ldap_result_add_search(
    mut lres: *mut ldap_result,
    mut ldap: *mut LDAP,
    mut searchresult: *mut LDAPMessage,
) -> *mut ldap_search_result {
    let mut news: *mut ldap_search_result = std::ptr::null_mut::<ldap_search_result>();
    unsafe {
        debug_decl!(SUDOERS_DEBUG_LDAP!());
    }

    unsafe {
        news = calloc(
            1 as libc::c_int as libc::c_ulong,
            ::std::mem::size_of::<ldap_search_result>() as libc::c_ulong,
        ) as *mut ldap_search_result;
        if !news.is_null() {
            (*news).ldap = ldap;
            (*news).searchresult = searchresult;
            (*news).entries.stqe_next = std::ptr::null_mut::<ldap_search_result>();
            *(*lres).searches.stqh_last = news;
            (*lres).searches.stqh_last = &mut (*news).entries.stqe_next;
        }
    } //unsafe

    unsafe {
        debug_return_ptr!(news);
    }
}

#[no_mangle]
pub fn sudo_ldap_bind_s(mut ld: *mut LDAP) -> libc::c_int {
    let mut ret: libc::c_int = 0;
    unsafe {
        debug_decl!(SUDOERS_DEBUG_LDAP!());
    }

    unsafe {
        if ldap_conf.rootuse_sasl == 1 as libc::c_int
            || ldap_conf.rootuse_sasl != 0 as libc::c_int && ldap_conf.use_sasl == 1 as libc::c_int
        {
            let mut old_ccname: *const libc::c_char = std::ptr::null::<libc::c_char>();
            let mut new_ccname: *const libc::c_char = ldap_conf.krb5_ccname;
            let mut tmp_ccname: *const libc::c_char = std::ptr::null::<libc::c_char>();
            let mut auth_id: *mut libc::c_void = (if !(ldap_conf.rootsasl_auth_id).is_null() {
                ldap_conf.rootsasl_auth_id
            } else {
                ldap_conf.sasl_auth_id
            }) as *mut libc::c_void;
            let mut rc: libc::c_int = 0;
            let sudo_debug_subsys_4: libc::c_int = *sudoers_subsystem_ids
                .as_mut_ptr()
                .offset(6 as libc::c_int as isize)
                as libc::c_int;

            if (ldap_conf.krb5_ccname).is_null() && !(sudo_user.krb5_ccname).is_null() {
                tmp_ccname = sudo_krb5_copy_cc_file(sudo_user.krb5_ccname);
                new_ccname = tmp_ccname;
                if tmp_ccname.is_null() {
                    sudo_debug_printf2_v1(
                        get_function_name!(),
                        get_file_name!(),
                        line!() as libc::c_int,
                        SUDO_DEBUG_INFO | SUDO_DEBUG_LINENO | sudo_debug_subsys_4 as libc::c_int,
                        b"unable to copy user ccache %s\0" as *const u8 as *const libc::c_char,
                        sudo_user.krb5_ccname,
                    );
                }
            }

            if !new_ccname.is_null() {
                rc = sudo_set_krb5_ccache_name(new_ccname, &mut old_ccname);
                if rc == 0 as libc::c_int {
                    sudo_debug_printf2_v1(
                        get_function_name!(),
                        get_file_name!(),
                        line!() as libc::c_int,
                        SUDO_DEBUG_INFO | SUDO_DEBUG_LINENO | sudo_debug_subsys_4 as libc::c_int,
                        b"set ccache name %s -> %s\0" as *const u8 as *const libc::c_char,
                        if !old_ccname.is_null() {
                            old_ccname
                        } else {
                            b"(none)\0" as *const u8 as *const libc::c_char
                        },
                        new_ccname,
                    );
                } else {
                    sudo_debug_printf2_v1(
                        get_function_name!(),
                        get_file_name!(),
                        line!() as libc::c_int,
                        SUDO_DEBUG_WARN | SUDO_DEBUG_LINENO | sudo_debug_subsys_4 as libc::c_int,
                        b"sudo_set_krb5_ccache_name() failed: %d\0" as *const u8
                            as *const libc::c_char,
                        rc,
                    );
                }
            }

            ret = ldap_sasl_interactive_bind_s(
                ld,
                ldap_conf.binddn,
                ldap_conf.sasl_mech,
                std::ptr::null_mut::<*mut LDAPControl>(),
                std::ptr::null_mut::<*mut LDAPControl>(),
                2 as libc::c_uint,
                Some(
                    sudo_ldap_sasl_interact
                        as unsafe extern "C" fn(
                            *mut LDAP,
                            libc::c_uint,
                            *mut libc::c_void,
                            *mut libc::c_void,
                        ) -> libc::c_int,
                ),
                auth_id,
            );

            if !new_ccname.is_null() {
                rc = sudo_set_krb5_ccache_name(
                    if !old_ccname.is_null() {
                        old_ccname
                    } else {
                        b"\0" as *const u8 as *const libc::c_char
                    },
                    std::ptr::null_mut::<*const libc::c_char>(),
                );
                if rc == 0 as libc::c_int {
                    sudo_debug_printf2_v1(
                        get_function_name!(),
                        get_file_name!(),
                        line!() as libc::c_int,
                        SUDO_DEBUG_INFO | SUDO_DEBUG_LINENO | sudo_debug_subsys_4 as libc::c_int,
                        b"restore ccache name %s -> %s\0" as *const u8 as *const libc::c_char,
                        new_ccname,
                        if !old_ccname.is_null() {
                            old_ccname
                        } else {
                            b"(none)\0" as *const u8 as *const libc::c_char
                        },
                    );
                } else {
                    sudo_debug_printf2_v1(
                        get_function_name!(),
                        get_file_name!(),
                        line!() as libc::c_int,
                        SUDO_DEBUG_WARN | SUDO_DEBUG_LINENO | sudo_debug_subsys_4 as libc::c_int,
                        b"sudo_set_krb5_ccache_name() failed: %d\0" as *const u8
                            as *const libc::c_char,
                        rc,
                    );
                }

                if !tmp_ccname.is_null() {
                    unlink(tmp_ccname);
                }
            }

            if ret != LDAP_SUCCESS {
                sudo_warnx!(
                    b"ldap_sasl_interactive_bind_s(): %s\0" as *const u8 as *const libc::c_char,
                    ldap_err2string(ret)
                );
                debug_return_int!(ret);
            }

            dprintf1!(
                b"ldap_sasl_interactive_bind_s(): %s() ok\0" as *const u8 as *const libc::c_char,
            );
        } else {
            let mut bv: berval = berval {
                bv_len: 0,
                bv_val: std::ptr::null_mut::<libc::c_char>(),
            };
            bv.bv_val = (if !(ldap_conf.bindpw).is_null() {
                ldap_conf.bindpw
            } else {
                b"\0" as *const u8 as *const libc::c_char
            }) as *mut libc::c_char;
            bv.bv_len = strlen(bv.bv_val);

            ret = ldap_sasl_bind_s(
                ld,
                ldap_conf.binddn,
                std::ptr::null_mut::<libc::c_char>(),
                &mut bv,
                std::ptr::null_mut::<*mut LDAPControl>(),
                std::ptr::null_mut::<*mut LDAPControl>(),
                std::ptr::null_mut::<*mut berval>(),
            );

            if ret != LDAP_SUCCESS {
                sudo_warnx!(
                    b"ldap_sasl_bind_s(): %s\0" as *const u8 as *const libc::c_char,
                    ldap_err2string(ret)
                );
                debug_return_int!(ret);
            }

            dprintf1!(b"ldap_sasl_bind_s() ok\0" as *const u8 as *const libc::c_char,);
        }
    } //unsafe //else
      //done; debug_return_int!(ret);

    unsafe {
        debug_return_int!(ret);
    }
}

#[no_mangle]
unsafe extern "C" fn sudo_ldap_close(mut nss: *mut sudo_nss) -> libc::c_int {
    let mut handle: *mut sudo_ldap_handle = (*nss).handle as *mut sudo_ldap_handle;
    debug_decl!(SUDOERS_DEBUG_LDAP!());

    if !handle.is_null() {
        if !((*handle).ld).is_null() {
            ldap_unbind_ext_s(
                (*handle).ld,
                std::ptr::null_mut::<*mut LDAPControl>(),
                std::ptr::null_mut::<*mut LDAPControl>(),
            );
            (*handle).ld = std::ptr::null_mut::<LDAP>();
        }

        if !((*handle).pw).is_null() {
            sudo_pw_delref((*handle).pw);
        }
        free_parse_tree(&mut (*handle).parse_tree);
        free(handle as *mut libc::c_void);
        (*nss).handle = std::ptr::null_mut::<libc::c_void>();
    }

    debug_return_int!(0);
}

#[no_mangle]
pub unsafe extern "C" fn sudo_ldap_open(mut nss: *mut sudo_nss) -> libc::c_int {
    let mut current_block: u64;
    let mut ld: *mut LDAP = std::ptr::null_mut::<LDAP>();
    let mut rc: libc::c_int = -(1 as libc::c_int);
    let mut ldapnoinit: bool = 0 as libc::c_int != 0;
    let mut handle: *mut sudo_ldap_handle = std::ptr::null_mut::<sudo_ldap_handle>();
    let sudo_debug_subsys_5: libc::c_int = *sudoers_subsystem_ids
        .as_mut_ptr()
        .offset(6 as libc::c_int as isize)
        as libc::c_int;
    debug_decl!(SUDOERS_DEBUG_LDAP!());

    if !((*nss).handle).is_null() {
        sudo_debug_printf2_v1(
            get_function_name!(),
            get_file_name!(),
            line!() as libc::c_int,
            SUDO_DEBUG_ERROR | sudo_debug_subsys_5 as libc::c_int,
            b"%s: called with non-NULL handle %p\0" as *const u8 as *const libc::c_char,
            get_function_name!(),
            (*nss).handle,
        );
        sudo_ldap_close(nss);
    }

    if !sudo_ldap_read_config() {
        debug_return_int!(if rc == LDAP_SUCCESS { 0 } else { -1 })
    }

    if sudo_getenv(b"LDAPNOINIT\0" as *const u8 as *const libc::c_char).is_null()
        && sudo_setenv(
            b"LDAPNOINIT\0" as *const u8 as *const libc::c_char,
            b"1\0" as *const u8 as *const libc::c_char,
            1 as libc::c_int,
        ) == 0 as libc::c_int
    {
        ldapnoinit = true;
    }

    /*if sudo_getenv(b"LDAPNOINIT\0" as *const u8 as *const libc::c_char).is_null() {
        if sudo_setenv(
            b"LDAPNOINIT\0" as *const u8 as *const libc::c_char,
            b"1\0" as *const u8 as *const libc::c_char,
            1 as libc::c_int,
        ) == 0 as libc::c_int
        {
            ldapnoinit = true;
        }
    }*/

    if sudo_ldap_set_options_global() != LDAP_SUCCESS {
        debug_return_int!(if rc == LDAP_SUCCESS { 0 } else { -1 })
    }

    if !(ldap_conf.uri.stqh_first).is_null() {
        let mut buf: *mut libc::c_char = sudo_ldap_join_uri(&mut ldap_conf.uri);
        if buf.is_null() {
            debug_return_int!(if rc == LDAP_SUCCESS { 0 } else { -1 })
        }
        dprintf2!(
            b"ldap_initialize(ld, %s)\0" as *const u8 as *const libc::c_char,
            buf
        );
        rc = ldap_initialize(&mut ld, buf);
        free(buf as *mut libc::c_void);
    } else {
        rc = sudo_ldap_init(&mut ld, ldap_conf.host, ldap_conf.port);
    }

    if rc != LDAP_SUCCESS {
        sudo_warnx!(
            b"unable to initialize LDAP: %s\0" as *const u8 as *const libc::c_char,
            ldap_err2string(rc)
        );
        debug_return_int!(if rc == LDAP_SUCCESS { 0 } else { -1 })
    }

    rc = sudo_ldap_set_options_conn(ld);
    if rc != LDAP_SUCCESS {
        debug_return_int!(if rc == LDAP_SUCCESS { 0 } else { -1 })
    }

    if ldapnoinit {
        sudo_unsetenv(b"LDAPNOINIT\0" as *const u8 as *const libc::c_char);
    }

    if ldap_conf.ssl_mode == SUDO_LDAP_STARTTLS {
        rc = ldap_start_tls_s(
            ld,
            std::ptr::null_mut::<*mut LDAPControl>(),
            std::ptr::null_mut::<*mut LDAPControl>(),
        );
        if rc != LDAP_SUCCESS {
            sudo_warnx!(
                b"ldap_start_tls_s(); %s\0" as *const u8 as *const libc::c_char,
                ldap_err2string(rc)
            );
            debug_return_int!(if rc == LDAP_SUCCESS { 0 } else { -1 })
        }
        dprintf1!(b"ldap_start_tls_s() ok\0" as *const u8 as *const libc::c_char,);
    }

    rc = sudo_ldap_bind_s(ld);
    if rc != LDAP_SUCCESS {
        debug_return_int!(if rc == LDAP_SUCCESS { 0 } else { -1 })
    }

    handle = calloc(
        1 as libc::c_int as libc::c_ulong,
        ::std::mem::size_of::<sudo_ldap_handle>() as libc::c_ulong,
    ) as *mut sudo_ldap_handle;

    if handle.is_null() {
        sudo_warnx!(
            b"%s: %s\0" as *const u8 as *const libc::c_char,
            get_function_name!(),
            b"unable to allocate memory\0" as *const u8 as *const libc::c_char
        );
        rc = -1;
        debug_return_int!(if rc == LDAP_SUCCESS { 0 } else { -1 });
    }

    (*handle).ld = ld;
    init_parse_tree(
        &mut (*handle).parse_tree,
        std::ptr::null::<libc::c_char>(),
        std::ptr::null::<libc::c_char>(),
    );
    (*nss).handle = handle as *mut libc::c_void;

    debug_return_int!(if rc == LDAP_SUCCESS { 0 } else { -1 });
}

#[no_mangle]
pub unsafe extern "C" fn sudo_ldap_getdefs(mut nss: *mut sudo_nss) -> libc::c_int {
    let mut current_block: u64;
    let mut handle: *mut sudo_ldap_handle = (*nss).handle as *mut sudo_ldap_handle;
    let mut tv: timeval = timeval {
        tv_sec: 0,
        tv_usec: 0,
    };
    let mut tvp: *mut timeval = std::ptr::null_mut::<timeval>();
    let mut base: *mut ldap_config_str = std::ptr::null_mut::<ldap_config_str>();
    let mut entry: *mut LDAPMessage = std::ptr::null_mut::<LDAPMessage>();
    let mut result: *mut LDAPMessage = std::ptr::null_mut::<LDAPMessage>();
    let mut filt: *mut libc::c_char = std::ptr::null_mut::<libc::c_char>();
    let mut rc: libc::c_int = 0;
    let mut ret: libc::c_int = -(1 as libc::c_int);
    static mut cached: bool = false;
    let sudo_debug_subsys_5: libc::c_int = *sudoers_subsystem_ids
        .as_mut_ptr()
        .offset(6 as libc::c_int as isize)
        as libc::c_int;

    if handle.is_null() {
        sudo_debug_printf2_v1(
            get_function_name!(),
            get_file_name!(),
            line!() as libc::c_int,
            SUDO_DEBUG_ERROR | sudo_debug_subsys_5 as libc::c_int,
            b"%s: called with NULL handle\0" as *const u8 as *const libc::c_char,
            get_function_name!(),
        );
        debug_return_int!(-1);
    }

    if cached {
        debug_return_int!(0);
    }

    filt = sudo_ldap_build_default_filter();
    if filt.is_null() {
        sudo_warnx!(
            b"%s: %s\0" as *const u8 as *const libc::c_char,
            get_function_name!(),
            b"unable to allocate memory\0" as *const u8 as *const libc::c_char
        );
        debug_return_int!(-1);
    }
    dprintf1!(
        b"Looking for cn=defaults: %s\0" as *const u8 as *const libc::c_char,
        filt
    );

    base = ldap_conf.base.stqh_first;
    while !base.is_null() {
        let mut ld: *mut LDAP = (*handle).ld;

        if ldap_conf.timeout > 0 {
            tv.tv_sec = ldap_conf.timeout as libc::c_long;
            tv.tv_usec = 0;
            tvp = &mut tv;
        }
        ldap_msgfree(result);
        result = std::ptr::null_mut::<LDAPMessage>();

        rc = ldap_search_ext_s(
            ld,
            ((*base).val).as_mut_ptr(),
            0x2 as libc::c_int,
            filt,
            std::ptr::null_mut::<*mut libc::c_char>(),
            0 as libc::c_int,
            std::ptr::null_mut::<*mut LDAPControl>(),
            std::ptr::null_mut::<*mut LDAPControl>(),
            tvp,
            0 as libc::c_int,
            &mut result,
        );

        if rc == 0 as libc::c_int && {
            entry = ldap_first_entry(ld, result);
            !entry.is_null()
        } {
            dprintf1!(
                b"found:%s\0" as *const u8 as *const libc::c_char,
                ldap_get_dn(ld, entry)
            );
            if !sudo_ldap_parse_options(ld, entry, &mut (*handle).parse_tree.defaults) {
                ldap_msgfree(result);
                free(filt as *mut libc::c_void);
                debug_return_int!(ret);
            }
        } else {
            dprintf1!(
                b"no default options found in %s\0" as *const u8 as *const libc::c_char,
                (*base).val
            );
        }
        base = (*base).entries.stqe_next;
    }
    cached = true;
    ret = 0;

    //goto done:
    ldap_msgfree(result);
    free(filt as *mut libc::c_void);
    debug_return_int!(ret);
}

#[no_mangle]
pub unsafe extern "C" fn ldap_entry_compare(
    mut a: *const libc::c_void,
    mut b: *const libc::c_void,
) -> libc::c_int {
    let mut aw: *const ldap_entry_wrapper = a as *const ldap_entry_wrapper;
    let mut bw: *const ldap_entry_wrapper = b as *const ldap_entry_wrapper;
    debug_decl!(SUDOERS_DEBUG_LDAP!());

    debug_return_int!(if (*aw).order < (*bw).order {
        -1
    } else if (*aw).order > (*bw).order {
        1
    } else {
        0
    });

    /*} else {
        if (*aw).order > (*bw).order {
            1
        } else {
            0
        }
    });*/
}

#[no_mangle]
pub fn sudo_ldap_result_last_search(mut lres: *mut ldap_result) -> *mut ldap_search_result {
    unsafe {
        debug_decl!(SUDOERS_DEBUG_LDAP!());

        debug_return_ptr!(if ((*lres).searches.stqh_first).is_null() {
            std::ptr::null_mut::<ldap_search_result>()
        } else {
            ((*lres).searches.stqh_last as *mut libc::c_char).offset(-(0 as libc::c_ulong as isize))
                as *mut ldap_search_result
        })
    }
}

#[no_mangle]
fn sudo_ldap_result_add_entry(
    mut lres: *mut ldap_result,
    mut entry: *mut LDAPMessage,
) -> *mut ldap_entry_wrapper {
    let mut last: *mut ldap_search_result = std::ptr::null_mut::<ldap_search_result>();
    let mut bv: *mut *mut berval = std::ptr::null_mut::<*mut berval>();
    let mut order: libc::c_double = 0.0f64;
    let mut ep: *mut libc::c_char = std::ptr::null_mut::<libc::c_char>();
    let mut rc: libc::c_int = 0;
    unsafe {
        debug_decl!(SUDOERS_DEBUG_LDAP!());
    }

    last = sudo_ldap_result_last_search(lres);
    unsafe {
        if !last.is_null() {
            bv = sudo_ldap_get_values_len(
                (*last).ldap,
                entry,
                b"sudoOrder\0" as *const u8 as *const libc::c_char as *mut libc::c_char,
                &mut rc,
            );
            if rc == LDAP_NO_MEMORY as libc::c_int {
                sudo_warnx!(
                    b"%s: %s\0" as *const u8 as *const libc::c_char,
                    get_function_name!(),
                    b"unable to allocate memory\0" as *const u8 as *const libc::c_char
                );
            } else {
                if ldap_count_values_len(bv) > 0 as libc::c_int {
                    dprintf2!(
                        b"order attribute raw: %s\0" as *const u8 as *const libc::c_char,
                        (**bv).bv_val
                    );
                    order = strtod((**bv).bv_val, &mut ep);
                    if ep == (**bv).bv_val || *ep as libc::c_int != '\u{0}' as i32 {
                        sudo_warnx!(
                            b"invalid sudoOrder attribute: %s\0" as *const u8
                                as *const libc::c_char,
                            (**bv).bv_val
                        );
                        order = 0.0f64;
                    }
                    dprintf2!(
                        b"order attribute: %f\0" as *const u8 as *const libc::c_char,
                        order
                    );
                }
                ldap_value_free_len(bv);
            }
        }

        (*lres).nentries = ((*lres).nentries).wrapping_add(1);
        if (*lres).nentries > (*lres).allocated_entries {
            let mut allocated_entries: libc::c_int = ((*lres).allocated_entries)
                .wrapping_add(ALLOCATION_INCREMENT as libc::c_int as libc::c_uint)
                as libc::c_int;

            let mut entries: *mut ldap_entry_wrapper = reallocarray(
                (*lres).entries as *mut libc::c_void,
                allocated_entries as size_t,
                ::std::mem::size_of::<ldap_entry_wrapper>() as libc::c_ulong,
            ) as *mut ldap_entry_wrapper;

            if entries.is_null() {
                debug_return_ptr!(std::ptr::null_mut::<ldap_entry_wrapper>());
            }
            (*lres).allocated_entries = allocated_entries as libc::c_uint;
            (*lres).entries = entries;
        }

        (*((*lres).entries)
            .offset(((*lres).nentries).wrapping_sub(1 as libc::c_int as libc::c_uint) as isize))
        .entry = entry;
        (*((*lres).entries)
            .offset(((*lres).nentries).wrapping_sub(1 as libc::c_int as libc::c_uint) as isize))
        .order = order;
    } //unsafe

    unsafe {
        debug_return_ptr!(&mut *((*lres).entries)
            .offset(((*lres).nentries).wrapping_sub(1 as libc::c_int as libc::c_uint) as isize,)
            as *mut ldap_entry_wrapper);
    }
}

#[no_mangle]
pub fn sudo_ldap_result_get(mut nss: *mut sudo_nss, mut pw: *mut passwd) -> *mut ldap_result {
    let mut current_block: u64;
    unsafe {
        let mut handle: *mut sudo_ldap_handle = (*nss).handle as *mut sudo_ldap_handle;
        let mut base: *mut ldap_config_str = std::ptr::null_mut::<ldap_config_str>();
        let mut lres: *mut ldap_result = std::ptr::null_mut::<ldap_result>();
        let mut tv: timeval = timeval {
            tv_sec: 0,
            tv_usec: 0,
        };
        let mut tvp: *mut timeval = std::ptr::null_mut::<timeval>();
        let mut entry: *mut LDAPMessage = std::ptr::null_mut::<LDAPMessage>();
        let mut result: *mut LDAPMessage = std::ptr::null_mut::<LDAPMessage>();
        let mut ld: *mut LDAP = (*handle).ld;
        let mut filt: *mut libc::c_char = std::ptr::null_mut::<libc::c_char>();
        let mut pass: libc::c_int = 0;
        let mut rc: libc::c_int = 0;

        debug_decl!(SUDOERS_DEBUG_LDAP!());
        lres = sudo_ldap_result_alloc();

        'oom: loop {
            if lres.is_null() {
                break 'oom;
            }

            pass = 0;
            while pass < 2 {
                filt = if pass != 0 {
                    sudo_ldap_build_pass2()
                } else {
                    sudo_ldap_build_pass1(ld, pw)
                };
                if !filt.is_null() {
                    dprintf1!(
                        b"ldap search '%s'\0" as *const u8 as *const libc::c_char,
                        filt
                    );

                    base = ldap_conf.base.stqh_first;
                    while !base.is_null() {
                        dprintf1!(
                            b"searching from base '%s'\0" as *const u8 as *const libc::c_char,
                            (*base).val
                        );
                        if ldap_conf.timeout > 0 as libc::c_int {
                            tv.tv_sec = ldap_conf.timeout as __time_t;
                            tv.tv_usec = 0 as libc::c_int as __suseconds_t;
                            tvp = &mut tv;
                        }
                        result = std::ptr::null_mut::<LDAPMessage>();
                        rc = ldap_search_ext_s(
                            ld,
                            ((*base).val).as_mut_ptr(),
                            LDAP_SCOPE_SUBTREE as libc::c_int,
                            filt,
                            std::ptr::null_mut::<*mut libc::c_char>(),
                            0 as libc::c_int,
                            std::ptr::null_mut::<*mut LDAPControl>(),
                            std::ptr::null_mut::<*mut LDAPControl>(),
                            tvp,
                            0 as libc::c_int,
                            &mut result,
                        );

                        if rc != LDAP_SUCCESS {
                            dprintf1!(
                                b"searching from base '%s'\0" as *const u8 as *const libc::c_char,
                                (*base).val
                            );
                            ldap_err2string(rc);
                            base = (*base).entries.stqe_next;
                            continue;
                        }

                        dprintf1!(b"adding search result\0" as *const u8 as *const libc::c_char,);
                        if (sudo_ldap_result_add_search(lres, ld, result)).is_null() {
                            break 'oom;
                        }

                        entry = ldap_first_entry(ld, result);
                        while !entry.is_null() {
                            if pass != 0 {
                                match sudo_ldap_check_non_unix_group(ld, entry, pw) {
                                    -1 => {
                                        break 'oom;
                                    }
                                    0 => {
                                        entry = ldap_next_entry(ld, entry);
                                        continue;
                                    }
                                    _ => {}
                                }
                            }
                            if sudo_ldap_result_add_entry(lres, entry).is_null() {
                                break 'oom;
                            }
                            entry = ldap_next_entry(ld, entry);
                        }

                        dprintf1!(
                            b"result now has %d entries\0" as *const u8 as *const libc::c_char,
                            (*lres).nentries
                        );
                        base = (*base).entries.stqe_next;
                    }
                    free(filt as *mut libc::c_void);
                    filt = std::ptr::null_mut::<libc::c_char>();
                } else if *__errno_location() != ENOENT {
                    break 'oom;
                }
                pass += 1;
            } //same as for

            if (*lres).nentries != 0 {
                dprintf1!(
                    b"sorting remaining %d entries\0" as *const u8 as *const libc::c_char,
                    (*lres).nentries
                );
                qsort(
                    (*lres).entries as *mut libc::c_void,
                    (*lres).nentries as size_t,
                    ::std::mem::size_of::<ldap_entry_wrapper>() as libc::c_ulong,
                    Some(
                        ldap_entry_compare
                            as unsafe extern "C" fn(
                                *const libc::c_void,
                                *const libc::c_void,
                            ) -> libc::c_int,
                    ),
                );
            }

            debug_return_ptr!(lres);
            break 'oom;
        } //end of oom:loop
        sudo_warnx!(
            b"%s: %s\0" as *const u8 as *const libc::c_char,
            get_function_name!(),
            b"unable to allocate memory\0" as *const u8 as *const libc::c_char
        );
        free(filt as *mut libc::c_void);
        sudo_ldap_result_free(lres);
    } //unsafe
    unsafe {
        debug_return_ptr!(std::ptr::null_mut::<ldap_result>());
    }
}

#[no_mangle]
pub unsafe extern "C" fn sudo_ldap_query(
    mut nss: *mut sudo_nss,
    mut pw: *mut passwd,
) -> libc::c_int {
    let mut handle: *mut sudo_ldap_handle = (*nss).handle as *mut sudo_ldap_handle;
    let mut lres: *mut ldap_result = std::ptr::null_mut::<ldap_result>();
    let mut ret: libc::c_int = -(1 as libc::c_int);
    let sudo_debug_subsys_7: libc::c_int = *sudoers_subsystem_ids
        .as_mut_ptr()
        .offset(6 as libc::c_int as isize)
        as libc::c_int;
    debug_decl!(SUDOERS_DEBUG_LDAP!());

    if handle.is_null() {
        sudo_debug_printf2_v1(
            get_function_name!(),
            get_file_name!(),
            line!() as libc::c_int,
            SUDO_DEBUG_ERROR | sudo_debug_subsys_7 as libc::c_int,
            b"%s: called with NULL handle\0" as *const u8 as *const libc::c_char,
            get_function_name!(),
        );
        debug_return_int!(-1);
    }

    'done: loop {
        if !(*handle).pw.is_null() {
            if pw == (*handle).pw {
                ret = 0;
                break 'done;
            }
            sudo_pw_delref((*handle).pw);
            (*handle).pw = std::ptr::null_mut::<passwd>();
        }

        free_userspecs(&mut (*handle).parse_tree.userspecs);

        dprintf1!(
            b"%s: ldap search user %s, host %s\0" as *const u8 as *const libc::c_char,
            get_function_name!(),
            (*pw).pw_name,
            sudo_user.runhost
        );
        lres = sudo_ldap_result_get(nss, pw);
        if lres.is_null() {
            break 'done;
        }

        if !ldap_to_sudoers((*handle).ld, lres, &mut (*handle).parse_tree.userspecs) {
            break 'done;
        }

        sudo_pw_addref(pw);
        ret = 0;

        break 'done;
    } // end of loop:done
    sudo_ldap_result_free(lres);
    if ret == -1 {
        free_userspecs(&mut (*handle).parse_tree.userspecs);
    }
    debug_return_int!(ret);
} //end

#[no_mangle]
pub unsafe extern "C" fn sudo_ldap_parse(mut nss: *mut sudo_nss) -> *mut sudoers_parse_tree {
    let mut handle: *mut sudo_ldap_handle = (*nss).handle as *mut sudo_ldap_handle;
    let sudo_debug_subsys_8: libc::c_int = *sudoers_subsystem_ids
        .as_mut_ptr()
        .offset(6 as libc::c_int as isize)
        as libc::c_int;
    debug_decl!(SUDOERS_DEBUG_LDAP!());

    if handle.is_null() {
        sudo_debug_printf2_v1(
            get_function_name!(),
            get_file_name!(),
            line!() as libc::c_int,
            SUDO_DEBUG_ERROR | sudo_debug_subsys_8 as libc::c_int,
            b"%s: called with NULL handle\0" as *const u8 as *const libc::c_char,
            get_function_name!(),
        );
        debug_return_ptr!(std::ptr::null_mut::<sudoers_parse_tree>());
    }

    debug_return_ptr!((&mut (*handle).parse_tree) as *mut sudoers_parse_tree);
}

#[no_mangle]
pub static mut sudo_nss_ldap: sudo_nss = unsafe {
    {
        sudo_nss {
            entries: {
                C2RustUnnamed_6 {
                    tqe_next: 0 as *const sudo_nss as *mut sudo_nss,
                    tqe_prev: 0 as *const *mut sudo_nss as *mut *mut sudo_nss,
                }
                //init
            },
            open: Some(sudo_ldap_open as unsafe extern "C" fn(*mut sudo_nss) -> libc::c_int),
            close: Some(sudo_ldap_close as unsafe extern "C" fn(*mut sudo_nss) -> libc::c_int),
            parse: Some(
                sudo_ldap_parse as unsafe extern "C" fn(*mut sudo_nss) -> *mut sudoers_parse_tree,
            ),
            query: Some(
                sudo_ldap_query as unsafe extern "C" fn(*mut sudo_nss, *mut passwd) -> libc::c_int,
            ),
            getdefs: Some(sudo_ldap_getdefs as unsafe extern "C" fn(*mut sudo_nss) -> libc::c_int),
            handle: 0 as *const libc::c_void as *mut libc::c_void,
            parse_tree: 0 as *const sudoers_parse_tree as *mut sudoers_parse_tree,
            ret_if_found: false,
            ret_if_notfound: false,
        }
        //init
    }
};
